在上一篇中学习了urllib库的基本使用,通过它我们可以完成爬虫中发送请求和处理响应的大部分功能,但在实际使用中多少会很繁琐,比如处理Cookie时需要创建handler和opener对象。正因为如此,就有了一个更友好且更强大的库requests,通过它我们也可以完成网页请求和处理,并且比urllib库显得更为简洁明了。
安装方法
可以直接通过pip进行安装:pip install requests
发送GET请求
使用requests发送GET请求只需要调用函数get(),并传入参数url即可,其在成功请求获取响应后返回一个<requests.models.Response>类的对象,该对象具有text,content,cookies,url,encoding和status_code等可访问的属性。
##示例1——使用requests.get发送GET请求 import requests # 获取请求内容的两种方法: text和content response = requests.get("http://www.baidu.com") print(type(response.text)) # <class 'str'> print(response.text) print(type(response.content)) # <class 'bytes'> print(response.content.decode('utf-8')) # 其他属性 print(response.url) # http://www.baidu.com/ print(response.encoding) # ISO-8859-1 print(response.status_code) # 200
这里要注意的是有两个属性都可以获取请求的内容:text属性是根据浏览器设置自动地“猜测”内容的编码方式而进行相应解码为字符串,这可能会存有误差;而content属性是获取源生网络编码字节流(bytes型),这种方式较为安全,在后续需要进行人工解码处理。
同样,爬虫在发送请求时,也有必要添加一些参数数据或请求头以反-反爬虫。在requests中,实现这一功能也极为简单,只需在请求函数中添加相应的参数即可。其中参数数据为字典类型,使用时requests会自动对其进行格式化编码,有多个参数时也会一并转化。
##示例2——设置参数和请求头来获取网页信息 import requests # 设置参数和请求头 params ={ 'wd':'博客园' } headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36' } # 发送请求 response = requests.get('https://www.baidu.com/s',params=params,headers=headers) # 写入(下载)文件 with open('baidu.html','w',encoding='utf-8')as fp: fp.write(response.content.decode('utf-8'))
发送POST请求
和get请求方法类似,调用post方法并传入相应参数即可。在此以拉勾网为例获取其职位信息,通过分析可获知其信息来源于图示的url中
##示例3——使用requests.post发送请求 import requests # 设置参数数据和请求头 data = { 'first': 'true', 'pn': '1', 'kd': 'python' } headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36', 'Referer':'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=', 'Cookie':'_ga=GA1.2.137369075.1536744524; user_trace_token=20180912172845-3f423c38-b66e-11e8-95a0-525400f775ce; LGUID=20180912172845-3f423ed0-b66e-11e8-95a0-525400f775ce; index_location_city=%E5%85%A8%E5%9B%BD; ab_test_random_num=0; hasDeliver=0; showExpriedIndex=1; showExpriedCompanyHome=1; showExpriedMyPublish=1; JSESSIONID=ABAAABAAAGFABEFEF1E1759C0E030B3417EBFF13B4E1731; _gat=1; LGSID=20180914232144-e370852e-b831-11e8-b93f-5254005c3644; PRE_UTM=; PRE_HOST=cn.bing.com; PRE_SITE=https%3A%2F%2Fcn.bing.com%2F; PRE_LAND=https%3A%2F%2Fwww.lagou.com%2F; Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1536744563,1536928793,1536938503; _putrc=3387DFFF4453A44E123F89F2B170EADC; login=true; unick=%E6%8B%89%E5%8B%BE%E7%94%A8%E6%88%B78638; gate_login_token=6284ccc0764f7fee185fe38407784e7cc3e472a013120475179916821e6cdfad; Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1536938511; LGRID=20180914232152-e867958b-b831-11e8-b93f-5254005c3644; TG-TRACK-CODE=search_code; SEARCH_ID=5aad6e88f4e64f42959a2aae9a5363c4' } # 发送请求 response = requests.post('https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false', data=data, headers=headers) print(response.json())
这里需说明的是,由于请求url内容为json数据,为方便查看,可使用json()方法返回其字典类型的数据。
使用代理
在requests中也可以使用代理服务器,使用方法也非常简单,在请求方法中加上proxies参数(字典类型)即可。
##示例4——使用代理服务器 import requests # 未使用代理发送请求 response = requests.get('http://httpbin.org/ip') print(response.text) # 使用代理发送请求 proxy = { 'http':'61.145.203.234:38695' } response = requests.get('http://httpbin.org/ip',proxies=proxy) print(response.text)
使用Session维持会话
由于HTTP请求的无状态性,在网页请求中常常需要利用一些数据以维护用户身份状态,在此过程中我们可以使用cookie来完成这一工作。然而,cookie的设置是一个比较繁琐的过程,而在requests中,有一个数据对象专门为我们简化了这一系列的工作,它可帮助我们自动地处理,并且能提供能加完备的功能——Session对象。
下面以登陆人人网并访问一用户主页为例
##示例5—— 使用session维持会话 import requests # 设置url,参数数据和请求头 url ='http://www.renren.com/SysHome.do' data = { 'email':'example@one.com', 'password':'123456' } headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36' } # 创建session并发送登陆请求 session = requests.session() session.post(url,data=data,headers=headers) # 此后便可利用同一个session以登录状态访问网页 response = session.get('http://www.renren.com/880151247/profile') print(response.content.decode('utf-8'))
不信任SSL证书网页的处理
在前面学习中提到过HTTP与HTTPS两种协议的区别,即HTTPS是HTTP的SSL加密版本,通常为国际认证的安全协议。我们有时候所请求的网页不一定拥有此认证,对于这些url,当我们正常情况下使用requests发送请求时会返回错误。若要允许访问非认证网页,则只需要在请求方法中添加参数’verify=False’,即忽略是否认证。
##示例6——处理请求未认证的网页 import requests response = requests.get('https://kyfw.12306.cn/otn/index/init',verify=False) print(response.content.decode('utf-8'))