Requests是Python的一个很实用的HTTP客户端库,完全满足如今网络爬虫的需求。与Urllib对比,Requests不仅具备Urllib的全部功能;在开发使用上,语法简单易懂,完全符合Python优雅、简洁的特性;在兼容性上,完全兼容Python 2和Python3,具有较强的适用性,操作更加人性化。
Requests库作为python的第三方库,可以通过pip安装,如下所示:
pip install requests
。sudo pip install requests
。 除了使用pip安装之外,还可以下载whl文件安装,不过步骤较为复杂,这里就不多做介绍。
值得一提的是Requests是一个开源库,源码位于GitHub:https://github.com/kennethreitz/requests,大家如果想下载最新版本,可以直接到GitHub上下载Requests的源代码,下载链接为:https://github.com/kennethreitz/requests/releases。将源代码压缩包进行解压,然后进入解压后的文件夹,运行setup.py文件即可。
HTTP的常用请求是GET和POST, Requests对此区分两种不同的请求方式。
import requests url = 'https://baidu.com/' # GET请求 r = requests.get(url, params=params, headers=headers, proxies=proxies, verify=True, cookies=cookies) # POST请求 r = requests.post(url, data=data, files=files,headers=headers, proxies=proxies, verify=True, cookies=cookies)
GET请求有两种形式,分别是不带参数和带参数,例如:
# 不带参数 https://www.baidu.com/ # 带参数wd https://www.baidu.com/s?wd=python
判断URL是否带有参数,可以对==符号“?”==判断。一般网址末端(域名)带有“?”,就说明该URL是带有请求参数的,反之则不带有参数。GET参数说明如下:
Requests实现GET请求,对于带参数的URL有两种请求方式:
import requests # 第一种方式 r = requests.get('https://www.baidu.com/s?wd=python') # 第二种方式 url = 'https://www.baidu.com/s' params = {'wd':'python'} r = requests.get(url, params=params) # 输出生成的URL print(r.url)
两种方式都是可以的,第二种方式是通过字典的形式传入参数和参数值,效果等同,在实际开发中建议使用第一种方式,因为代码简洁,如果参数是动态变化的,那么可使用字符串格式化对URL动态设置, 例如:'https://www.baidu.com/s?wd=%s' %('python')
。
POST请求是我们常说的提交表单,表单的数据内容就是POST的请求参数。**Requests实现POST请求需设置请求参数data,数据格式可以为字典、元组、列表和JSON格式,**不同的数据格式有不同的优势。
# 字典类型 data = {'key1':'value1', 'key2':'value2'} # 元组或列表 (('key1', 'value1'), ('key2', 'value2')) # JSON import json data = {'key1':'value1', 'key2':'value2'} # 将字典转换JSON data = json.dumps(data) # 发送POST请求 import requests r = requests.post("https://www.baidu.com/", data=data) print(r.text)
复杂的请求方式通常有请求头、代理IP、证书验证和Cookies等功能。Requests将这一系列复杂的请求做了简化,将这些功能在发送请求中以参数的形式传递并作用到请求中。
(1)添加请求头:请求头以字典的形式生成,然后发送请求中设置的headers参数,指向已定义的请求头。
headers = { 'User-Agent':'......', '...':'...', ...... } requests.get("https://www.baidu.com/", headers=headers)
添加请求头headers是解决requests请求反爬的方法之一,相当于我们进去这个网页的服务器本身,假装自己本身在爬取数据。解决了在请求网页爬取的时候,输出的text信息中会出现抱歉,无法访问等字眼的问题。
(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)
由于我们使用python爬虫在网站爬取东西,一个固定IP的访问频率就会很高,这不符合人为操作的标准,因为人操作不可能在几ms内,进行如此频繁的访问。所以一些网站会设置一个IP访问频率的阈值,如果一个IP访问频率超过这个阈值,说明这个不是人在访问,而是一个爬虫程序。那么我们的IP就可能被封,而且自己的IP也可能被查找出来,这时我们就可以使用一些高匿代理IP来满足我们更大的需要。
(3)证书验证:通常设置关闭验证即可。在请求设置参数verify=False时就能关闭证书的验证,默认情况下是True。如果需要设置证书文件,那么可以设置参数verify值为证书路径。
一般的网页都有认证证书,所以一般requests请求时不添加这个参数,但是仍有可能访问的网页没有认证证书,这时就可以关闭证书验证。不过关闭验证运行程序会爆红,但是仍能正常运行,没有影响
(4)超时设置:发送请求后,由于网络、服务器等因素,请求到获得响应会有一个时间差。如果不想程序等待时间过长或者延长等待时间,可以设定timeout的等待秒数,超过这个时间之后停止等待响应。如果服务器在timeout秒内没有应答,将会引发一个异常。
requests.get('https://www.baidu.com', timeout = 5) requests.post('https://www.baidu.com', timeout = 5)
(5)设置Cookies:在请求过程中使用Cookies也只需设置参数Cookies即可。Cookies的作用是标识用户身份,在Requests中以字典或RequestsCookieJar对象作为参数。获取方式主要是从浏览器读取和程序运行所产生。
import requests test_cookies = 'JSESSIONID=2C30FCABDBF3B92E358E3D4FCB69C95B; Max-Age=172800;' cookies = {} # 分割,将字符串转换成字典格式 for i in test_cookies.split(';'): value = i.split('=') cookies[value[0]] = value[1] r = requests.get(url, cookies=cookies) print(r.text)
当程序发送请求时(不设参数cookies),会自动生成一个RequestsCookieJar对象,该对象用于存放Cookies信息。
import requests url = 'https://www.baidu.com/' r = requests.get(url) # r.cookies是RequestsCookieJar对象 print(r.cookies) thecookies = r.cookies # RequestsCookieJar转换为字典 cookie_dict = requests.utils.dict_from_cookiejar(thecookies) print(cookie_dict) # 字典转换RequestsCookieJar cookie_jar = requests.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True) print(cookie_jar) # 在RequestsCookieJar对象中添加Cookies字典 print(requests.utils.add_dict_to_cookiejar(thecookies, cookie_dict))
当向网站(服务器)发送请求时,网站会返回相应的响应(response)对象,包含服务器响应的信息。Requests提供以下方法获取响应内容。
注意:在获得响应内容时可以使用r.text,但是有时会出现解码错误,获得乱码的情况,这是获得的编码格式不正确,可以通过r.encoding进行查看,也可以r.encoding = ‘…’ 来指定正确的编码格式,一般网页的编码为utf-8(也有可能是gbk)。
但是这种手动的方式略显笨拙,下面提供一种更加简便的方式:chardet,这是一个很好的字符串/文件编码检测模块。
首先安装模块:pip install chardet
安装完成后,使用chardet.detect()返回字典,其中confidence是检测精确度,encoding是编码形式。
import requests r = requests.get('http://www.baidu.com') print(chardet.detect(r.content)) # 将chardet探测到的编码赋给r.encoding实现解码 r.encoding = chardet.detect(r.content)['encoding'] print(r.text)