版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Song_Lynn/article/details/82944927
python3爬虫(一):请求库之requests
Request是基于urllib编写、采用Apache2 Licensed开源协议的HTTP库,在使用方面Requests比urllib更加方便
一、HTTP请求
1. GET
requests.get(url [, params={‘key’: ‘value’}])
- 通过url的查询字符串传递数据时,数据以键值对的形式跟在url的一个问号之后
- Requests允许使用params关键字参数传递数据
注意:
- 字典中值为None的键不会添加到查询字符串中
- 键值可以是列表
import requests
# 无查询字符串
res1 = requests.get('http://www.baidu.com')
# 有查询字符串
data2 = {
'key1': 'value1',
'key2': 'value2'
}
res2 = requests.get('http://www.xxx.com', params=data)
print(res2) # http://www.xxx.com?key1=value1&key2=value2
# 查询字符串中有列表
data3 = {
'key1': 'value1',
'key2': ['value2', 'value3']
}
res3 = requests.get('http://www.xxx.com', params=data)
print(res3) # http://www.xxx.com?key1=value1&key2=value2&key2=value3
2. POST
requests.post(url [, data={‘key’: ‘value’}, json={‘key’: ‘value’}])
- 以字典形式提交表单数据
- 可以传入一个元组列表,尤其是表单中多个元素使用同一key
- 发送数据并非编码为表单形式。如传递一个string,会被直接发布出去
- 除自行对dict进行编码,可以使用json参数直接传递,会被自动编码
import requests
url = 'http://www.xxx.com'
# 传递字典
data1 = {
'name': '12345',
'age': '23'
}
res1 = requests.post(url, data=data1)
# 传递元组
data2 = (('key1', 'value1'), ('key1', 'value2'))
res2 = requests.post(url, data=data2)
import json
data3 = {'some': 'data'}
res3 = requests.post(url, data=json.dumps(payload))
# 数据未编码
data4 = {'some': 'data'}
res4 = requests.post(url, json=data4)
3. PUT
requests.put(url [, data={‘key’: ‘value’}])
以字典形式提交表单数据
import requests
url = 'http://www.xxx.com'
data = {
'name': '12345',
'age': '23'
}
res = requests.put(url, data=data)
4. DELETE
requests.delete(url)
import requests
res = requests.delete(url)
5. HEAD
requests.head(url)
import requests
res = requests.head(url)
6. OPTIONS
requests.options(url)
import requests
res = requests.options(url)
二、头部信息
- 为所有请求(get, post, put, delete等)添加HTTP头部信息,只需要传递一个字典dict给headers参数
- 所有的header值类型:string, bytestring, unicode(不建议使用unicode)
- 大小写不敏感
注意:定制header的优先级低于某些特定的信息源
import requests
url = 'http://www.baidu.com'
headers = {'user-agent': 'xxxxxxxxxxxxxx'}
res = requests.get(url, headers=headers)
三、Respone对象
使用requests方法后,会返回 respone 对象,存储了服务器相应内容
- res.text:读取已被解码的服务器响应的内容
- 基于HTTP头部对响应的编码作出的推测进行内容编码
- 能够使用 res.encoding 来改变编码方式
import requests
res - requests.get('https://api.github.com/events')
pirnt(res.text) # u'[{"repository":{"open_issues":0,"url":"https://github.com/...
- res.encoding:响应内容的编码方式
- getter:查询当前响应内容的编码方式
- setter:改变当前响应内容的编码方式
- res.content:二进制响应内容
- 以字节的形式访问请求响应体
- 会自动解码 gzip 和 deflate 传输编码的响应数据
import requests
res - requests.get('https://api.github.com/events')
pirnt(res.content) # b'[{"repository":{"open_issues":0,"url":"https://github.com/...
# 请求返回的二进制数据创建一张图片
from PIL import Image
from io import BytesIO
i = Image.open(BytesIO(res.content))
- res.json():返回JSON数据
- 内置的JSON解码器,有助于处理JSON数据
- 解码失败,则会抛出一个异常
注意:调用 res.json() 成功不意味着响应成功(有时响应失败也会包含一个JSON对象)
import requests
res - requests.get('https://api.github.com/events')
pirnt(res.json()) # [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
- res.raw:原始响应内容
- 在初始请求中设置 stream=True
- 可以使用 res.iter_content(xxx)处理大量直接使用 res.raw 不得不处理的
res = requests.get('https://api.github.com/events', stream=True)
print(res.raw) # <requests.packages.urllib3.response.HTTPResponse object at 0x101194810>
print(res.raw.read(10)) # '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
# 一般情况下,以下面的模式将文本刘保存到文件
with open(filename, 'wb') as fd:
for chunk in r.iter_content(chunk_size):
fd.write(chunk)
- res.status_code:检测响应的状态码
- 可以使用 Requests 内置的状态码 requests.codes.xx 查询对象
res = resquests.get('http://www.xxx.com')
print(res.status_code) # 200
print(res.status_code == requests.code.ok) # True
-
res.raise_for_status():抛出异常
- 当发送了错误请求,可使用 res.raise_for_status() 来抛出异常
- 当发送了正确请求时,res.raise_for_status()返回None
-
res.headers:查看服务器响应头
- 以字典 dict 形式展示响应头
- 大小写不敏感
- 服务器可以多次接受同一header,每次都使用不同的值,但Requests胡将它们合并
-
res.cookies:访问响应中的cookie
-
res.history:追踪重定向
四、Cookie
1. 访问cookies
使用 respone.cookies 访问服务器响应中包含的cookie
url = 'http://www.xxx.com'
res = requests.get(url)
print(res.cookies)
2. 发送cookies
- 发送HTTP请求时,使用 cookies 参数
- 类型:
- 字典 dict
- RequestsCookieJar对象(行为与字典类似,但接口更为完整,适合跨域名、跨路径使用)
url = 'http://www.xxx.com'
cookies1 = {'key': 'value'}
res1 = requests.get(url, cookies.cookies1)
cookies2 = requests.cookies.RequestsCookieJar()
cookies2.set('key', 'value', domain='...', path='...') # domain:有效域,path:有效路径
res2 = resquests.get(url, cookies=cookies2)
五、文件上传
发型POST请求时,使用 files 文件
- 上传多部分编码(Multipart-Encoded)文件
url = 'http://httpbin.org/post'
files = {'file': open('report.xls', 'rb')}
res = requests.post(url, files=files)
- 显示地设置文件名、文件类型、请求头
url = 'http://httpbin.org/post'
files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
res = requests.post(url, files=files)
- 发送作为文件来接受的字符串
url = 'http://httpbin.org/post'
files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}
res = requests.post(url, files=files)
注意:
- 发送一个非常大的文件作为 multipart/form-data 请求,requests不支持将请求做成数据流,但第三方包 requests-toolbelt支持
- 强烈建议用二进制模式(binary mode)打开文件(原因:Requests试图提供Content-Length header,会被设为文件的字节数),而不是文本模式(text mode)
六、重定向与请求历史
- 默认情况下,除了HEAD,Requests会自动处理所有重定向
- res.history是一个response对象的列表,按照从最老到最近的请求进行排序
- get, post, put, patch, delete, options请求可以通过 allow_redirects参数禁用重定向处理
- head请求也可以使用 allow_redirects 启用重定向
allow_redirects:默认为 True(启用)
七、超时 timeout
- 发送HTTP请求时,使用 timeout参数设定超时时间以停止等待响应
- 一般都应使用该参数
- 仅对连接过程有效,与响应提的下载无关
八、错误与异常
所有显示抛出的异常都继承自Requests.exceptions.RequestException
- 网络问题(DNS查询失败、拒绝连接等):Requests抛出 ConnectionError异常
- HTTP请求返回了不成功的状态码:Response.raise_for_status()抛出HTTPError异常
- 请求超时:Timeout异常
- 请求超过了设定的最大重定向次数:TooManyRedirects异常