【爬虫基础】Requests库
Requests是Python的一个很实用的HTTP客户端库。
与Urllib对比,Requests不仅具备Urllib的全部功能;在开发使用上,语法简单易懂,完全符合Python优雅、简洁的特性;在兼容性上,完全兼容Python2和Python3,具有较强的适用性。
安装
Requests可通过pip安装,还可以下载whl文件安装。
pip 是 Python 包管理工具,该工具提供了对Python 包的查找、下载、安装、卸载的功能; whl格式本质上是一个压缩包,里面包含了py文件,以及经过编译的pyd文件
请求方式
HTTP的常用请求是GET和POST,Requests对此区分两种不同的请求方式。
GET请求有两种形式,分别是不带参数和带参数,以百度为例:
#不带参数 https://www.baidu.com/ #带参数wd
https://www.baidu.com/s?wd=python
判断URL是否带有参数,可以对符号“?”判断。一般网址末端(域名)带有“?”,就说明该URL是带有请求参数的,反之则不带有参数。
GET参数说明如下:
(1)wd是参数名,参数名由网站(服务器)规定。
(2)python是参数值,可由用户自行设置。
(3)如果一个URL有多个参数,参数之间用“&”连接。
Requests实现GET请求,对于带参数的URL有两种请求方式:
import requests #第一种方式 r=requests.get('https://www.baidu.com/s?wd=python') #第二种方式 url='https://www.baidu.com/s' params={'wd':'python'}#左边params在GET请求中表示设置参数 r=requests.get(url,params=params) #输出生成的URL print(r.url)
两种方式都是请求同一个URL,在实际开发中建议使用第一种方式,因为代码简洁,如果参数是动态变化的,那么可使用字符串格式化对URL动态设置,例如htps://www.baidu.com/s?wd=os'%(python)。
POST请求是我们常说的提交表单,表单的数据内容就是POST的请求参数。
Requests实现POST 请求需设置请求参数data,数据格式可以为字典、元组、列表和JSON格式,不同的数据格式有不同的优势。代码如下:
#字典类型 data={'key1':'valuel','key2':'value2'} #元组或列表 ((’key1','value1'),('key1','value2')) #JSON import json data={'key1':'valuel','key2':'value2'} #将字典转换JSON data=json.dumps(data) #发送POST请求 r=requests.post("https://www.baidu.com/",data=data) print(r.text)
可以看出,左边的data是POST方法的参数,右边的data是发送请求到网站(服务器)的数据。
值得注意的是,Requests的GET和POST方法的请求参数分别是params和data,别混淆两者的使用要求。
当向网站(服务器)发送请求时,网站会返回相应的响应(response)对象,包含服务器响应的信息。Requests提供以下方法获取响应内容。
r.status_code:响应状态码。
r.raw:原始响应体,使用r.raw.read()读取。
r.content:字节方式的响应体,需要进行解码。
r.text:字符串方式的响应体,会自动根据响应头部的字符编码进行解码。
r.headers:以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在,则返回None。
r.json():Requests中内置的JSON解码器。
r.raise for status():请求失败(非200响应),抛出异常。
r.url:获取请求链接。
r.cookies:获取请求后的cookies。
r.encoding:获取编码格式。
进一步的请求方式
复杂的请求方式通常有请求头、代理IP、证书验证和Cookies等功能。
Requests将这一系列复杂的请求做了简化,将这些功能在发送请求中以参数的形式传递并作用到请求中。
(1)添加请求头:请求头以字典的形式生成,然后发送请求中设置的headers参数,指向已定义的请求头,代码如下:
headers={ 'content-type':'application/json',
User-Agent':'Mozilla/5.0(Windows NT 6.3;WOW64;rV:41.0)Gecko/20100101 Firefox/41.0'} requests.get("https://www.baidu.com/",headers=headers)
(2)使用代理IP:代理IP的使用方法与请求头的使用方法一致,设置proxies参数即可,代码如下:
import requests proxies={ "http":"http://10.10.1.10:3128", "https":"http://10.10.1.10:1080",
}
requests.get("https://www.baidu.com/",proxies=proxies)
(3)证书验证:通常设置关闭验证即可。在请求设置参数verify=False时就能关闭证书的验证,默认情况下是True。如果需要设置证书文件,那么可以设置参数verify值为证书路径。
import requests url='https://kyfw.12306.cn/otn/leftTicket/init' #关闭证书验证 r=requests.get(url,verify=False) print(r.status code) #开启证书验证 #r=requests.get(url,verify=True) #设置证书所在路径 #r=requests.get(url,verify=1/path/to/certfile')
(4)超时设置:发送请求后,由于网络、服务器等因素,请求到获得响应会有一个时间差。
如果不想程序等待时间过长或者延长等待时间,可以设定timeout的等待秒数,超过这个时间之后停止等待响应。如果服务器在timeout秒内没有应答,将会引发一个异常。使用代码如下:
requests.get("https://www.baidu.com/",timeout=0.001) requests.post("https://www.baidu.com/",timeout=0.001)
(5)使用Cookies:在请求过程中使用Cookies 也只需设置参数Cookies即可。Cookies的作用是标识用户身份,在Requests中以字典或RequestsCookieJar对象作为参数。获取方式主要是从浏览器读取和程序运行所产生。下面的例子进一步讲解如何使用Cookies,代码如下:
import requests temp cookies='JSESSIONID GDS=y4p7oSFr IYV5Udyd6c1drWE8MeTpQn0Y58Tg8cCONVPO 20y2N!450649273;name=value' cookies dict={} for i in temp cookies.split(';'):value=i.split('=') cookies dict[value[0]]=value[1] r=requests.get(url,cookies=cookies) print(r.text)
代码中变量temp_cookies是Cookies信息,可以在Chrome开发者工具一Network→某请求的Headers→Request Headers 中找到Cookie所对应的值。然后将字符串转换成字典格式,转换规则主要执行两次分割:第一次以“;”分割,得到列表A,第二次是列表A的每一个元素以“=”分割,得到字典的键值对。
当程序发送请求时(不设参数cookies),会自动生成一个RequestsCookieJar对象,该对象用于存放Cookies信息。Requests提供RequestsCookieJar对象和字典对象的相互转换,代码如下:
import requests
url='https://movie.douban.com/'
r=requests.get(url)
#r.cookies是RequestsCookieJar对象
print(r.cookies)
mycookies=r.cookies
#RequestsCookieJar转换字典
cookies dict=requests.utils.dict from cookiejar(mycookies)
print(cookies dict)
#字典转换RequestscookieJar cookies jar=requests.utils.cookiejar from dict(cookies dict,cookiejar=None,overwrite=True)
print(cookies jar)
#在RequestsCookieJar 对象添加 Cookies字典中print(requests.utils.add dict to cookiejar(mycookies,cookies dict))
如果要将Cookies写入文件,可使用http模块实现Cookies的读写。除此之外,还可以将Cookies以字典形式写入文件,此方法相比http模块读写Cookies更为简单,但安全性相对较低。使用方法如下:
(略)
下载与上传
下载文件主要从服务器获取文件内容,然后将内容保存到本地。下载文件的方法如下:
import requests ur1='https://www.python.org/static/img/python-1ogo.png' r=requests.get(url) f=open('python.jpg','wb') #r.content获取响应内容(字节流) f.write(r.content) f.close()
服务器将文件内容作为响应内容,然后将得到的内容以字节流(Bytes)格式写入自定义文件,这样就能实现文件下载。
除了文件下载外,还有更为复杂的文件上传,文件上传是将本地文件以字节流的方式上传到服务器,再由服务器接收上传内容,并做出相应的响应。文件上传存在一定的难度,其难点在于服务器接收规则不同,不同的网站接收的数据格式和数据内容会不一致。(略)