Requests get爬虫之设置headers
本文作者:王碧琪 文字编辑:钱梦璇 技术总编:张 邯
前段时间,粉丝在抓取网页数据时,使用 requests
中的 get
方法,标注了url,却始终得不到数据。后来,经过一番尝试之后才发现,加上headers之后,想要的数据就出来了,不禁心生疑问:为什么要加headers呢?今天,我们就来聊一聊requests get爬虫时设置headers的相关内容。get方法请求指定的页面信息,并返回实体主体。语法是:requests.get(url,kwargs)
。其中,url是我们想要访问的链接,kwargs是可选参数,包括params、data、json、headers、cookies、auth、files、timeout、proxies、stream、verify、cert等,常用的可选参数有data、headers。
一、不需要设置headers
有时, get
方式不设置headers可以行得通。例如,我们用get方法访问百度首页:
import requests
r1= requests.get("https://www.baidu.com")
print(r1)
结果是:
<Response [200]>
此处的200是HTTP响应的状态码的一种,200表示该请求被成功完成,所请求的资源发送到客户端。其他的部分状态码如下所示:
状态码 | 含义 |
---|---|
100 | 客户端必须继续发出请求。 |
101 | 客户端要求服务器根据请求转换HTTP协议版本。 |
200 | 表明该请求被成功地完成,所请求的资源发送到客户端。 |
201 | 提示知道新文件的URL。 |
202 | 接受并处理,但处理未完成。 |
203 | 返回信息不确定或不完整。 |
204 | 收到请求,但返回信息为空。 |
205 | 服务器完成了请求,用户必须复位当前已经浏览过的文件。 |
206 | 服务器已经完成了部分用户的GET请求。 |
300 | 请求的资源可在多处获得。 |
301 | 本网页被永久性转移到另一个URL。 |
302 | 请求的网页被重定向到新的地址。 |
303 | 建议用户访问其他URL或访问方式。 |
304 | 自从上次请求后,请求的网页未修改过。 |
305 | 请求的资源必须从服务器指定的地址获得。 |
306 | 前一版本HTTP中使用的代码,现已不再使用。 |
307 | 声明请求的资源临时性删除。 |
400 | 客户端请求有语法错误。 |
401 | 请求未经授权。 |
402 | 保留有效ChargeTo头响应。 |
403 | 禁止访问,服务器收到请求,但拒绝提供服务。 |
404 | 可连接服务器,但服务器无法取得所请求的网页,请求资源不存在。 |
405 | 用户在Request-Line字段定义的方法不被允许。 |
406 | 根据用户发送的Accept,请求资源不可访问。 |
407 | 类似401,用户必须首先在代理服务器上取得授权。 |
408 | 客户端没有在用户指定的时间内完成请求。 |
409 | 对当前资源状态,请求不能完成。 |
410 | 服务器上不再有此资源。 |
411 | 服务器拒绝用户定义的Content-Length属性请求。 |
412 | 一个或多个请求头字段在当前请求中错误。 |
413 | 请求的资源大于服务器允许的大小。 |
414 | 请求的资源URL长于服务器允许的长度。 |
415 | 请求资源不支持请求项目格式。 |
416 | 请求中包含Range请求头字段,在当前请求资源范围内没有range指示值。 |
417 | 服务器不满足请求Expect头字段指定的期望值。 |
500 | 服务器错误。 |
501 | 服务器不支持请求的功能。 |
502 | 网关错误。 |
503 | 无法获得服务。 |
504 | 网关超时。 |
505 | 不支持的http版本。 |
我们把网页源代码打印出来:
print(r1.text)
二、需要设置headers
有时只标注url却得不到数据或者得不到全部数据,会显示抱歉、无法访问等字眼。例如,我们用get方法访问一个淘宝页面:https://item-paimai.taobao.com/pmpitem/609160317276.htm?s=pmpdetail&spm=a213x.7340941.2001.61.1aec2cb6RKlKoy,想要得到这个网址https://item-paimai.taobao.com/api/pmp/34078065117276/bid-list?ksTS=1576480179404132&callback=jsonp133中对应的bidBasic信息。
我们点击Headers,此处的request url就是我们需要写在get里的链接。
r2=requests.get("https://item-paimai.taobao.com/api/pmp/34078065117276/bid-list?_ksTS=1576480179404_132&callback=jsonp133")
print(r2)
print(r2.text)
with open(r'g:/r2.txt','w') as f:
f.write(r2.text)
结果是:
表示成功访问,并且返回了数据。但是小编想要的是bidBasic并不在里面,例如搜索一下第一个bidBasic的bidPrice:1900100,结果显示为无。
为什么明明在preview中显示出来,而用get去抓取得时候却出现了不一样的东西?小编加上了request headers,再利用get方式来试试。
headers={
'accept': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'cookie': '_tb_token_=berT80V49uJ9PFEJKGPI; cna=IhV+FpiDqRsCAXE54OSIgfFP; v=0; t=bb1c685b877ff64669f99c9dade7042c; cookie2=1e5103120f9886062722c86a5fad8c64; uc1=cookie14=UoTbm8P7LhIRQg%3D%3D; isg=BJWVw-e2ZCOuRUDfqsuI4YF0pJFFPHuu_ffxbBc6UYxbbrVg3-JZdKMoODL97mFc; l=dBMDiW9Rqv8wgDSFBOCiVZ9JHt_OSIRAguWfypeMi_5Zl681GgQOkUvZ8FJ6VjWftBTB4tm2-g29-etki6jgwbd6TCNQOxDc.',
'referer': 'https://item-paimai.taobao.com/pmp_item/609160317276.htm?s=pmp_detail&spm=a213x.7340941.2001.61.1aec2cb6RKlKoy',
'sec-fetch-mode': 'cors',
"sec-fetch-site": 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
'x-requested-with': 'XMLHttpRequest'
}
r3=requests.get("https://item-paimai.taobao.com/api/pmp/34078065117276/bid-list?_ksTS=1576480179404_132&callback=jsonp133",headers=headers)
print(r3)
print(r3.text)
with open(r'g:/r3.txt','w') as f:
f.write(r3.text)
结果是:
打开源代码文件:
这一次,我们才拿到了想要的数据了。不设置headers就进行抓取得不到目标数据,这其实是网页的一种反爬机制。一种可能是网页设置可能限制了必须要从某个页面才能点击进入下一个页面,如果直接进入后一个链接,将会识别为机器所为,不是真实的人在操作,还有可能是网页会识别采用什么终端进行访问,即headers中的user-agent,我们利用手机、平板、电脑访问同一网址可能得到不一样的页面内容就是因为这个原因。当然,headers里的信息有的很长,每个都有其特定的含义,设计者最终选择的反爬方案可能出现在其中的任何一条。
所以,为了保险起见,我们在使用requests get爬取网页源代码时,无脑加上所有headers即可,这样可以省掉很多麻烦。
关于我们
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。