requests库
一、简介
1.简介
Requests是一个优雅而简单的Python HTTP库,是有史以来下载次数最多的Python软件包之一,作者是Kenneth Reitz
2. 安装
pip install requests
3.官方文档
中文文档:http://cn.python-requests.org/zh_CN/latest/
英文文档:http://docs.python-requests.org/en/master/
二、发起请求
0.参数总览
def request(self, method, url,
params=None, data=None, headers=None, cookies=None, files=None,
auth=None, timeout=None, allow_redirects=True, proxies=None,
hooks=None, stream=None, verify=None, cert=None, json=None)
1.请求方法
每一个请求都有各自对应的方法,每一个请求方法都有一个对应的API
import requests
res = requests.get('https://www.baidu.com')
res = requests.post('https://www.baidu.com')
res = requests.head('https://www.baidu.com')
res = requests.put('https://www.baidu.com')
res = requests.delete('https://www.baidu.com')
res = requests.options('https://www.baidu.com')
POST请求使用post()方法,并且将需要提交的数据传递给data参数即可,data表示form表单
import requests
data = {"key": "value"}
res = requests.post('https://httpbin.org/post', data=data)
2.构造链接
传递URL参数时可以构造一个字典,并在请求时将其传递给params参数
import requests
params = {"name": "zzh", "age": "18"}
res = requests.get('https://www.baidu.com', params=params)
print(res.url) # https://www.baidu.com/?name=zzh&age=18
相同的url参数名,但有不同的值,而python的字典又不支持键的重名,则可以把键的值用列表表示
import requests
params = {"key1": "value1", "key2": ["value2", "value3"]}
res = requests.get('https://www.baidu.com', params=params)
print(res.url) # https://www.baidu.com/?key1=value1&key2=value2&key2=value3
3.文件上传
上传文件时可以构造一个字典,键为自定义名称,值为需上传的文件,并在请求时将其传给files参数,注意上传的文件应与当前脚本位于同一目录下
import requests
files = {"image": open('1.jpg', 'rb')}
res = requests.get('https://httpbin.org/post', files=files)
4.自定义Handers
遇到一些验证User-Agent的网站时,需要我们自定义Headers参数来传递头信息把自己伪装成浏览器
import requests
headers = {
'User-Agent': 'Mozilla/5.0(Macintosh;IntelMacOSX10_7_0)AppleWebKit/535.11(KHTML,likeGecko)'
'Chrome/17.0.963.56Safari/535.11'
}
res = requests.get('https://httpbin.org', headers=headers)
5.自定义Cookies
法一:直接将字典递给cookies参数
import requests
cookies = {'cookie': 'working'}
res = requests.get('https://httpbin.org/get', cookies=cookies)
法二:在headers参数中含有cookie参数,设置好传入headers参数
import requests
headers = {
'cookie': 'cookie=working'
}
res = requests.get('https://httpbin.org/get', headers=headers)
6.代理设置
在大规模爬取时,由于大规模且频繁的操作,网站可能会弹出验证码,或者跳转到登录界面,更甚者会直接封禁客户端IP导致一定时间段内无法访问,因此需要使用代理,使用代理时同样构造代理字典,传递给proxies参数
import requests
proxies = {
'http': '221.182.89.234:63000',
'https': '221.182.89.234:63000'
}
res = requests.get('https://httpbin.org/ip', proxies=proxies)
7.重定向
在网络请求中,常会遇到状态码是3开头的重定向问题,在Requests中是默认开启允许重定向的,即遇到重定向时,会自动继续访问,将allow_redirects参数设为False,关闭重定向
import requests
res = requests.get('http://github.com', allow_redirects=True)
print(res.status_code) # 200
res = requests.get('http://github.com', allow_redirects=False)
print(res.status_code) # 301
8.SSL证书验证
当发送HTTP请求时,它会检查SLL证书,抓包工具提供的的证书并不是由受信任的数字证书颁发机构颁发的,所以证书的验证会失败,所以就需要使用verify参数控制是否检查此证书,默认为True,改为False即可关闭证书验证
import requests
res = requests.get('https://www.12306.cn', verify=False)
print(res.status_code)
***********************************************************************
D:\Python\lib\site-packages\urllib3\connectionpool.py:1004: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning,
200
但是关闭验证后,会有一个比较烦人的warning,建议我们指定证书,可以通过设置忽略警告的方式屏蔽这个警告
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
# 禁用安全请求警告
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
res = requests.get('https://www.12306.cn', verify=False)
print(res.status_code)
***********************************************************************
200
9.超时设置
为防止服务器不能及时响应,应设置超时响应,即超过此时间还没得到响应就报错。设置访问超时,修改timeout参数即可,此时间的计算是发送请求到服务器返回响应的时间
import requests
res = requests.get('http://www.taobao.com', timeout=0.1)
print(res.status_code)
***********************************************************************
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='www.taobao.com', port=443): Read timed out. (read timeout=0.1)
实际上,请求分为两个阶段,即连接和读取,timeout是这两者的总和,如果要分别设置,可以传入一个元组
import requests
res = requests.get('http://www.taobao.com', timeout=(1, 2))
print(res.status_code)
***********************************************************************
200
10.身份认证
在访问网页时,可能会遇见身份验证页面,如果用户名和密码都正确,请求时自动认证成功,返回状态码200,如果认证失败,返回状态码401。认证时可以直接传一个元组给auth参数,它会默认使用HTTPBasicAuth这个类来验证
import requests
res = requests.get('http://www.taobao.com', auth=('username', 'password'))
print(res.status_code) # 200
11.会话维持
会话对象让你能够跨请求保持某些参数,它也会在同一个 Session 实例发出的所有请求之间保持 cookie,所以如果向同一主机发送多个请求,底层的 TCP 连接将会被重用,从而带来显著的性能提升
# 首先请求了一个测试网站,请求网站时传了一个名称为sessioncookie,内容为123456789的cookie,随后又请求了测试网站,结果拿不到第一次请求时的Cookies
import requests
requests.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = requests.get("http://httpbin.org/cookies")
print(r.text) {"cookies": {}}
# 首先生成一个Session对象,然后用这个Session对象来发起访问,发起访问的方法与正常的请求是一摸一样的,结果可以取到第一次请求时的Cookies
import requests
s = requests.Session()
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get("http://httpbin.org/cookies")
print(r.text) # '{"cookies": {"sessioncookie": "123456789"}}'
# 让一个headers在Session的整个生命周期内都有效的方法
import requests
s = requests.Session()
# 增加一条Headers
s.headers.update({'key1': 'value1'})
s.get('http://httpbin.org/headers', headers={'key2': 'value2'}) # 此处定义的无法取到
print(s.headers)
***********************************************************************
{'User-Agent': 'python-requests/2.22.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'key1': 'value1'}
三、接收响应
1.text属性
text是一个方法利用@property
变成一个属性,所以调用时不用加(),返回的是文本内容,而文本内容的编码是基于HTTP头部猜测的,所以可能会出现乱码情况,可以通过.encoding
查看或修改编码类型
res = requests.get('http://www.baidu.com')
print(res.encoding) # ISO-8859-1
res.encoding = 'utf-8'
print(res.encoding) # utf-8
print(res.text) # utf-8编码格式的网页内容
2.content属性
content是一个方法利用@property
变成一个属性,返回的是二进制内容,多数用于抓取二进制数据(图片、音频、视频等),可以用decode()方法转为其他编码格式
import requests
res = requests.get('http://www.baidu.com')
print(res.content)
print(res.content.decode('utf-8'))
3.json()方法
调用json()方法,可以将返回结果是JSON格式的字符串转化成字典,返回结果如果不是JSON格式,就会出现解析错误并抛出json.decoder.JSONDecodeError
异常
import requests
res = requests.get('http://www.baidu.com')
print(res.json())
***********************************************************************
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
import requests
res = requests.get('http://httpbin.org/get')
print(res.json())
***********************************************************************
{'args': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0'}, 'origin': '218.24.192.193, 218.24.192.193', 'url': 'https://httpbin.org/get'}
4.其他
import requests
res = requests.get('http://httpbin.org/get')
print(res.url) # url
print(res.status_code) # 状态码
print(res.cookies) # cookie
print(res.headers) # 响应报头
***********************************************************************
http://httpbin.org/get
200
<RequestsCookieJar[]>
{'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'gzip', 'Content-Type': 'application/json', 'Date': 'Thu, 24 Oct 2019 00:17:22 GMT', 'Referrer-Policy': 'no-referrer-when-downgrade', 'Server': 'nginx', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'DENY', 'X-XSS-Protection': '1; mode=block', 'Content-Length': '185', 'Connection': 'keep-alive'}