如果你在使用python执行爬虫任务,那么你怎么能错过requets呢!作为标榜为人类服务的HTTP库,requests 的操作方式和浏览器在与服务器端交互时的方式极度相似,这极大的方便了爬虫的构建。
在 爬虫 | 浅析HTTP协议 中介绍了,客户端和服务器端交互时由客户端先发送请求,服务器端处理请求并返回响应。在利用python编写爬虫代码时也是同样的道理。
HTTP请求
利用 requests 发送HTTP请求时,首先要确认请求行:
主要视以下情况而定:
发送请求
首先要导入库:
import requests
然后,向某个网站发送请求,这里以 必应 首页为例,因为必应首页是个搜索页面,不需要登录即可使用,因此使用 HTTP协议中的 GET 方法:
cb = requests.get('http://cn.bing.com')
使用 GET 方法发送HTTP请求时,requests 库中同样使用的是 get 方法,这就是 requests 库比较人性化的地方。其请求方法与 HTTP协议中的请求方法是对应的。
上述的请求方式中,仅指定了请求行信息,并没有明确给出请求首部信息。有时为了防止被服务器端直接确认出时爬虫发送的请求,拒绝访问。我们需要给出一些请求首部信息来迷惑一部分服务器端。
请求首部
使用开发者工具可以看到,在请求 必应 主页时,浏览器发送请求的请求首部信息 (图中绿色框中信息):
其中包含了:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Cookie:SRCHD=AF=NOFORM; SRCHUID=V=2&GUID=CB2645996826443896976B7A995A7513&dmnchg=1; SRCHUSR=DOB=20170819; _EDGE_V=1; MUID=0B4E8CC2A9A8616E05148621A80960D1; MUIDB=0B4E8CC2A9A8616E05148621A80960D1; ipv6=hit=1; _FP=hta=on; _EDGE_S=mkt=zh-cn&F=1&SID=1E87FDAD83E7604438A3F74E82466173; SRCHHPGUSR=CW=811&CH=621&DPR=1&UTC=480&WTS=63638741890; _SS=SID=1E87FDAD83E7604438A3F74E82466173&bIm=94930:&HV=1503148606
Host:cn.bing.com
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
我们同样可以定制属于自己的请求头信息,然后在发送HTTP请求时传递给请求方法,headers 的值为 字典 形式:
url = http://cn.bing.com
header = {'User-Agent' : 'Chrome/60.0.3112.90',
'Accept-Encoding' : 'gzip, deflate',
'Host' : 'cn.bing.com'}
cb = requests.get(url, headers = header)
关于使用 headers 参数的注意事项,requests 官方文档中已经提及:
注意: 定制 header 的优先级低于某些特定的信息源,例如:
.netrc
中设置了用户认证信息,使用 headers= 设置的授权就不会生效。而如果设置了auth=
参数,``.netrc`` 的设置就无效了。带参数请求
通常登录网站需要验证用户信息的时候,发送的请求都会附加参数。比如在登录气象家园论坛时,需要验证用户信息。下面以登录气象家园论坛为例发送带参数请求:
In [12]: params = {'fastloginfield': 'username',
'username' : username,
'password' : passwd,
'quickforward' : 'yes',
'handlekey' : 'ls'}
In [14]: cookies = {'Cookie' : cookie_value}
In [15]: s = requests.post(loginurl, params = params, headers = header, cookies = cookies)
# 返回响应内容中检查到 用户名 表示登录成功
In [18]: s.text.find(username)
Out[18]: 5686
参数通过字典的方式给出,给出参数后 requests 会将参数整合到 URL 中 (关键信息已打码):
In [19]: s.url
Out[19]: 'http://bbs.06climate.com/member.php?password=*****&username=*****&fastloginfield=username&quickforward=yes&handlekey=ls'
如果键值为 None,那么此键不会被添加到 URL 中。更多使用方式见 官方文档。
HTTP响应
客户端发送请求后,服务器端返回的响应存储在 cb 对象中。首先读取 状态码 确定响应状态:
>> cb.status_code
200
状态码为 200 表示成功获取响应信息。
利用 .headers 属性可以获取响应头信息:
>> cb.headers
{'Cache-Control': 'private, max-age=0', 'Content-Length': '46812', 'Content-Type': 'text/html; charset=utf-8', 'Content-Encoding': 'gzip', 'Vary': 'Accept-Encoding', 'P3P': 'CP="NON UNI COM NAV STA LOC CURa DEVa PSAa PSDa OUR IND"', 'Set-Cookie': 'SRCHD=AF=NOFORM; domain=.bing.com; expires=Mon, 19-Aug-2019 12:46:40 GMT; path=/, SRCHUID=V=2&GUID=C0E5834B4B08488D98569FCED7F842CC&dmnchg=1; domain=.bing.com; expires=Mon, 19-Aug-2019 12:46:40 GMT; path=/, SRCHUSR=DOB=20170819; domain=.bing.com; expires=Mon, 19-Aug-2019 12:46:40 GMT; path=/, _SS=SID=07063060DF246A5D12463A83DE856B11; domain=.bing.com; path=/, _EDGE_S=F=1&SID=07063060DF246A5D12463A83DE856B11; path=/; httponly; domain=bing.com, _EDGE_V=1; path=/; httponly; expires=Mon, 19-Aug-2019 12:46:40 GMT; domain=bing.com, MUID=375A97DF43C962140B4B9D3C42686372; path=/; expires=Mon, 19-Aug-2019 12:46:40 GMT; domain=bing.com, MUIDB=375A97DF43C962140B4B9D3C42686372; path=/; httponly; expires=Mon, 19-Aug-2019 12:46:40 GMT', 'X-MSEdge-Ref': 'Ref A: 9A5F2DA1356F46D7949BC58832C5F416 Ref B: BJ1EDGE0319 Ref C: 2017-08-19T12:46:40Z', 'Date': 'Sat, 19 Aug 2017 12:46:40 GMT'}
requests 在获取页面内容的过程中会自动判断编码,然后进行解码。大多数情况下,这些都没什么问题。但是有时候还是会出现乱码情况,这时候就要改变编码以适应网页编码,从而解决乱码问题。以设置 ‘utf-8’ 编码为例:
cb.encoding = 'utf-8'
成功获取响应之后,我们主要关心的是网页的内容,即响应主体。获取响应主体:
cb.text
执行上述代码会返回网页内容为字符串。
Cookies
cookies 技术的引入就是为了解决持续连接的问题。对于购物网站来说这是非常重要的,省却了每更新一次网页就重新登录账号的麻烦。上面在登录气象家园论坛时也使用了 Cookie。
使用 cookies 参数即可添加 cookie 信息到 URL 中。
目前了解了 HTTP 协议,也了解了 requests 的一些简单用法。