Python网络爬虫MOOC听课笔记-第一周requests库

2019-09-04

在MOOC上,学习了北京理工大学,嵩天老师的Python网络爬虫与信息提取,此为学习笔记记录,备查,备翻阅复习。

P1.课程简介

北京理工大学 MOOC 向嵩

目的:掌握定向网络爬取和网页解析的能力

理念:the website is API

Requests 自动爬取网页,自动提交网络请求

robots.txt 网络爬虫排除标准

Beautiful Soup 解析HTML页面

Re 正则表达式库

P2. IDE选择

选择Python IDE

文本工具类 Sublime text, IDLE

集成工具类 Pycharm, Anacoda

P3.

P4. 第一周内容导学

  • Request库入门

  • Robotx协议

  • 爬虫实例

Requests库安装:pip install requests

Requests库7个主要方法

requests.request()

requests.get()

requests.head()

requests.post()

requests.put()

requests.patch()

requests.delete()

其实后面6个方法都是base第一个基础方法 requests.request()

r = requests.get(url, params = None, **kwargs)

Response对象 和

import requests
r = requests.get("http://www.baidu.com")
print(r.status_code)
type(r)
r.headers

r.encoding = 'utf-8'
r.text

r.encoding
r.apparent_encoding
r.encoding = 'UTF-8'
r.text

Response 对象的属性

  • r.status_code: 200表示成功,404或其他表示异常
  • r.text 字符串形式
  • r.encoding 从HTTP header中charset字段猜测的response的编码方式,如果不存在charset字段则默认编码为ISO-8859-1
  • r.apparent_encoding根据网页内容分析出的备选编码方式
  • r.content HTTP相应内容的二进制形式

爬取网页的通用代码框架

异常

requests.ConnectionError

requests.HTTPError

requests.URL.Required

requests.TooManyRedirects

requests.ConnectionTimeout 与服务器连接的过程超时异常

requests.Timeout 请求URL的整个过程超时异常

r.raise_for_status()

import requests

def getHTMLText(url):
   try:
       r = requests.get(url, timeout = 30)
       r.raise_for_status() #判断状态,不是200则引发Error
       r.encoding = r.apparent_encoding
       return r.text
    except:
       return "产生异常"

if __name__ =="__main__":
   url = "http://www.baidu.com"
   print(getHTMLText(url))

http协议

Hypertext transfer protocol超文本传输协议

基于”请求与相应”的模式

URL 是一个通过HTTP协议存取资源的internet路径

# url格式 http://host[:post][path]
# host 主机域名或IP地址
# port 端口号,缺省端口为80
# path 请求资源的路径

HTTP协议对网络数据资源的操作主要有6种

  • GET 请求获取URL位置的资源

  • HEAD 请求获取URL位置的资源时的响应消息报告,即获得该资源的头部信息

  • POST 向URL资源后新增数据,不改变元数据

  • PUT 向URL位置存储数据,会覆盖URL位置上的所有原数据

  • PATCH 局部更新URL位置中数据资源局部更新

  • DELETE 删除URL位置存储的数据资源

HTTP协议方法是与request库中的同名方法功能呢是一样的。

requests库主要方法介绍

requests.request()方法是基础,其他的6个方法的参数都是基于这个方法的。

# requests.request(method, url, **kwargs)
# method 就是GET, HEAD, POST, PUT,PATCH, DELETE, OPTIONS
# OPTIONS并不常用

**kwargs: 控制访问的参数,均为可选项,有13个:

params:字典或字节序列,作为参数增加到url中

data:字典或字节序列或文件数据,作为request内容

json:JSON格式数据,作为request内容

headers: 字典,HTTP定制头

cookies: 字典或CookieJar,

auth: 元组

files: 字典类型,传输文件

timeout: 设置超时时间,second为单位

proxy: 字典,设定访问代理服务器,可以增加登录认证

allow_redirects: True/False,默认为True,重定向开关

stream: True/False,默认为True,获取内容立即下载开关

verify: True/False,默认为True,认证SSL证书开关

cert: 本地SSL证书路径

对于爬虫来说,其实最常用的requests库重点掌握GET和HEAD。

网络爬虫的道德

网络爬虫的尺寸

  • 小规模 爬取网页 Requests库,绝大多数爬虫
  • 中规模 爬取网站 Scrapy库
  • 大规模 爬取全网 搜索引擎

网络爬虫带来的问题:

  • 骚扰服务器
  • 爬取有版权内容
  • 爬取有个人隐私的内容

网络爬虫的限制

  • 来源审查:判断User-Agent,只相应部分访问
  • 发布公告:Robotx协议,告知所有爬虫的爬取要遵守

Robots协议

网络爬虫排除标准

告知爬虫哪些可爬,哪些不可以。

在网站根目录下放robots.txt文件。

Robots协议基本语法: *代表所有, Disalow表示不允许。

User-agent: *

Disallow: /?*

不提供robots协议的网站即表示不限制爬虫访问。

Robots协议遵守方式

网络爬虫应该可以自动或者人工识别robots.txt,然后根据规则进行爬取。不遵守robots.txt的爬取,会存在法律风险。

不过类人行为的访问(比如访问频率很低),可以酌情不遵守robots.txt,但不能用于商业用途。

实例1:爬取京东商品页面

常规爬取

import requests
url = "https://item.jd.com/100003688077.html"
try:
    r = requests.get(url)
    r.raise_for_status() #判断状态,不是200则引发Error
    r.encoding = r.apparent_encoding
    print(r.text[:1000]) 
except:
    print("爬取失败")

实例2:亚马逊页面爬取

status 503报错.Amazon对来源进行审查。

需要修改request.get(url, header = kv)中的header字段

import requests
url = "https://www.amazon.cn/gp/product/B01M8L5Z3Y"

try:
    kv = {'user-agent':'Mozilla/5.0'}
    r = requests.get(url,headers = kv)
    r.raise_for_status() #判断状态,不是200则引发Error
    r.request.headers
    r.encoding = r.apparent_encoding
    print(r.text[1000:2000]) 
except:
    print("爬取失败")


实例3:百度360搜索关键词提交搜索

向搜索引擎提交关键词的爬虫

百度的关键词接口

# http://www.baidu.com/s?wd=keyword

360的关键词接口

# http://www.so.com/s?q=keyword

只需要修改keyword就可以向搜索引擎提交搜索关键词。

只需要用requests库构建这样的url即可。

# 逐行代码
import requests
kv = {'wd':'Python'}
r = requests.get("http://www.baidu.com/s", params = kv)
r.status_code
r.request.url
len(r.text)

# 百度搜索全代码框架
import requests
keyword = "Python"
try:
    kv = {'wd':keyword}
    r = requests.get("http://www.baidu.com/s", params = kv)
    print(r.request.url)
    r.raise_for_status()
    print(len(r.text)) # 437177
except:
     print("爬取失败")
# 360搜索的全代码,只有API接口的关键词换成了q
import requests
keyword = "Python"
try:
    kv = {'q':keyword}
    r = requests.get("http://www.so.com/s", params = kv)
    print(r.request.url)
    r.raise_for_status()
    print(len(r.text)) # 349167
except:
     print("爬取失败")

实例4:网络图片的爬取

网络图片链接的格式, 以.jpg结尾

# 逐行代码
import requests
path = "D:/abc.jpg"
url = "http://image.nationalgeographic.com.cn/2017/0211/20170211061910157.jpg"
r = requests.get(url)
r.status_code

with open(path, 'wb') as f:
    f.write(r.content)
    f.close()    

图片爬取全代码

import requests
import os
url = "http://image.nationalgeographic.com.cn/2017/0211/20170211061910157.jpg"
root = "F://pics//"
path = root + url.split('/')[-1]

try:
    if not os.path.exists(root):
        os.mkdir(root)
    if not os.path.exists(path):
        r = requests.get(url)
        with open(path, 'wb') as f:
            f.write(r.content)
            f.close()
            print('文件保存成功')
    else:
        print('文件已存在')
except:
    print("爬取失败")

实例5:IP地址归属地的自动查询

www.ip138.com 查询

可以发现,提交查询时,url是http://m.ip138.com/ip.asp?ip=ipaddress

分析网站的API接口,所以就可以爬取查询信息。

#逐行代码
import requests
url = "http://m.ip138.com/ip.asp?ip="
r = requests.get(url + '202.204.80.112')
r.status_code
r.text[-500]#查询返回文本的最后500个字符
#完整代码
import requests
url = "http://m.ip138.com/ip.asp?ip="
try:
    r = requests.get(url + '202.204.80.112')
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    print(r.text[-500:])
except:
    print("爬取失败")

该实例提示,对于需要在网页中进行提交信息查询时,可以挖掘一下这个网站的API是什么,然后考虑用爬虫实现。使用网络爬虫的视角来看待网络内容,也就是网络上所有的内容都有一个url,对网络上的内容只有两个基本点,一是url,一是基于http协议的6种操作。