您的位置:首页 > 产品设计 > UI/UE

使用requests库发送HTTP请求

2020-05-10 04:11 1131 查看

Requests官网上有这么一句话:Requests: HTTP for Humans。什么意思呢?就是说Requests是真正方便人类与HTTP进行交互的库。相比与urllib库,Requests真的是太方便了。目前Requests 支持 Python 2.6—2.7以及3.3—3.7。

通过这篇文章,你将能够知道:

  • 如何使用requests发送http请求(GET 、POST)
  • 如何对requests进行二次开发和定制

1、安装Requests

我的系统中安装了pipenv,我们通过它来创建一个虚拟环境使用requests。(如何安装pipenv?请点击)

$ mkdir requests_demo
$ cd requests_demo
$ pipenv --two #创建Python2的版本的虚拟环境
$ pipenv install requests --dev  # 将requests作为开发依赖安装到虚拟环境中
$ pipenv graph  # 查看是否成功,输出下方的信息表示安装成功了
requests==2.18.4
- certifi [required: >=2017.4.17, installed: 2018.1.18]
- chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
- idna [required: <2.7,>=2.5, installed: 2.6]
- urllib3 [required: <1.23,>=1.21.1, installed: 1.22]

2、基本使用方法

来创建一个简单的请求,来体验一下。

with requests.Session() as s: # 创建session
r = s.request('GET','https://api.github.com/repos/liuchunming033/pipenv')
print('请求对象:')
print(r.request.headers) # 获取请求对象的头
print(r.request.method) # 获取请求对象的请求方法
print(r.request.url) # 获取请求对象的请求url
print('响应对象:')
print(r.status_code) # 获取响应对象的状态码
print(r.headers) # 获取响应对象的响应头
print(r.text) # 获取响应对象的内容,文本格式
response = r.json() # 获取响应对象的内容,如果返回的是json格式。
print(response)

是不是很简单,请求发送出去之后,将会返回一个Response对象 r。通过这个响应对象,我们可以或得到很多有用的信息。如上面代码的注释那样。Response对象还包含有一个特别的Request对象r.request。
上面的请求放在with上下文管理器中,以便请求发送完成后,保证能关闭HTTP连接。

3、发送GET请求

3.1、简单的GET请求

简单的GET请求,类似上一章节介绍的那样。不在赘述。

3.2、设置请求的超时时间(默认没有超时时间)

通过传递timeout参数可以给请求设置超时时间。有两个超时时间可以设置,一个connect超时时间,一个是read超时时间,表示连接建立开始到发送第一个respone字节的时间。

with requests.Session() as s:
r1 = s.request('GET', 'https://github.com', timeout=(3.05, 27))  # 设置connect超时时间3.05s,read超时时间27s
r2 = s.request('GET', 'https://github.com', timeout=5)  # 设置connect超时时间和read超时时间都是5s
r3 = s.request('GET', 'https://github.com', timeout=None)  # 不设置超时时间
print(r1.elapsed) # 打印响应时间
print(r2.elapsed)
print(r3.elapsed)

3.3、发送带参数和头部的请求

通常的HTTP请求都是会包含请求头和请求参数的。
HTTP请求的头部信息包含了本次请求的重要附加信息,通常包含认证信息、请求的格式等。
GET请求的请求参数一般为了URL上面,在Rquests模块中,用param来指定。我们来看一个例子:

with requests.Session() as s:
headers = {'Authorization': "Bearer  VAHV0LaqfJBI8BM2n1iHfg=="}
querystring = {"app_id": "10000", "region": "cn", "lang": "zh-cn"}
r = s.request('GET', 'https://example.com', headers=headers,params = querystring,timeout = (3.05, 27))

上面这个请求的列子,带上了表示请求headers信息,头信息中包含了本次请求的认证信息,传递给request方法的headers参数,url上的请求参数传递给request方法的params参数。

3.5、发送单向认证的请求

3.6、发送双向认证的请求

4、发送POST请求

POST请求通常被用来向服务器提交数据,数据可以被编码成各种格式之后传递给服务器。通常的编码格式有application/x-www-form-urlencoded、application/json。这些都是接口定义时候,规定好的。我们按照定义的格式发送请求就好。

给服务器提交的数据,被传递给request方法的data参数。下面我们分别介绍这两种常用的请求格式如何发送HTTP请求。

4.1、发送json数据格式的请求

发送json格式的POST请求,需要将设置headers中的Content-Type为application/json。参考下面的例子:

with requests.Session() as s:
method = 'POST'
url = 'https://example.com'
headers = {'Content-Type': "application/json"}
querystring = {"app_id": "10000", "region": "cn", "lang": "zh-cn"}
payload = {"vehicle_model": "ES8", "version": "1.0"}
response = s.request(method, url, json=payload, headers=headers, params=querystring)

对于application/json格式的payload,只需要将Python字典类型传递给request的json参数。

4.2、发送urlencode格式的请求

4.2.1 普通上传

发送urlencode格式的POST请求,需要将设置headers中的Content-Type为application/x-www-form-urlencoded。参考下面的例子:

with requests.Session() as s:
method = 'POST'
url = 'https://example.com'
headers = {'Content-Type': "application/x-www-form-urlencoded"}
querystring = {"app_id": "10000", "region": "cn", "lang": "zh-cn"}
payload = {"vehicle_model": "ES8", "version": "1.0"}
response = s.request(method, url, data=payload, headers=headers, params=querystring)

对于urlencode格式的数据,直接将Python字典传递给request方法的data参数就可以了。

4.2.2、流式上传

在urlencode格式的接口中,可能会遇到这样的情况,比如一个接口包含10个参数,每个参数又可能是非常大的字符串,这将导致整个请求非常大,非常耗内存。为了解决这个问题,接口可以设计成将所有参数进行gzip压缩后,通过流式上传到服务器。requests正好支持这样的请求方式:

with requests.Session() as s:
method = 'POST'
url = 'https://example.com'
headers = {'Content-Type': "application/x-www-form-urlencoded",
"content-encoding": "gzip"}
payload = {"vehicle_model": "ES8", "version": "1.0"}
querystring = {"app_id": "10000", "region": "cn", "lang": "zh-cn"}
with gzip.open('/Users/chunming.liu/file.gz', 'w') as f:
f.write(json.dumps(payload))
with open('/Users/chunming.liu/file.gz', 'rb') as f:
s.request(method, url, data=f, params=querystring, headers=headers)

通过这样方式上传,需要在headers中指定”content-encoding”: “gzip”。另外,使用gzip.open对参数进行压缩。

4.3、发送上传文件的请求

4.3.1 上传单个文件

Requests使得上传多部分编码(Multipart-Encoded)的文件变得简单,Requests是先读取文件到内存中,然后再构造请求发送出去。通过设置filename、文件句柄、content_type 和 headers 组成file对象,传递给request的files参数,就可以上传文件了:

with requests.Session() as s:
method = 'POST'
url = 'https://example.com'
headers = {
'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
}
files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
r = s.request(method, url, headers=headers,files=files)
print r.text

headers中,multipart/form-data是必须的.
- - - - WebKitFormBoundary7MA4YWxkTrZu0gW是分隔符,分隔多个文件、表单项。

其中7MA4YWxkTrZu0gW是即时生成的,用以确保整个分隔符不会在文件或表单项的内容中出现。前面的—-WebKitFormBoundary代表的是Webkit,
- - - - - - - - - - - - - - - - - - - - - - - - - - - 7d 是 IE 特有的标志。 Mozila 为- - - - - - - - - - - - - - - - - - - - - - - - - - - 71。

4.3.2 上传多个文件

发送多个文件的话参考下面的代码,下面代码展示的是同时上传多个图片的情况:

with requests.Session() as s:
method = 'POST'
url = 'https://example.com'
headers = {
'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
}
multiple_files = [
('images', ('foo.png', open('foo.png', 'rb'), 'image/png')),
('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))]
r = s.request(method, url, headers=headers, files=multiple_files)
print r.text

4.3.3 发送大文件请求的最佳方式

如果需要发送一个非常大的文件作为 multipart/form-data 请求时,为了避免把大文件读取到内存中,我们就希望将请求做成数据流。
默认requests是不支持的(或很困难), 这时需要用到第三方包requests-toolbelt。

import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder

m = MultipartEncoder(
fields={'field0': 'value',
'field1': 'value',
'field2': ('upload.zip', open('upload.zip', 'rb'), 'application/zip')}
)

with requests.Session() as s:
r = s.request('http://httpbin.org/post', data=m,
headers={'Content-Type': m.content_type})
print r.text

5、二次开发

liuchunming033 博客专家 原创文章 192获赞 323访问量 178万+ 关注 他的留言板
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: