【Python】requests模块

文章目录

  • 初识requests
  • 安装requests
  • 快速上手
    • 发送请求
    • 传递URL数据
    • 响应内容
    • 二进制响应内容
    • JSON响应内容
    • 原始响应内容
    • 自定义请求头headers
    • 更复杂的POST请求
    • POST多部分编码的(Multipart-Encoded)文件

初识requests

首先通过与urllib2的对比认识一下 requests的强大功能:

>>> import requests
>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
>>> r.status_code
200
>>> r.headers['content-type']
'application/json; charset=utf8'
>>> r.encoding
'utf-8'
>>> r.text
u'{"type":"User"...'
>>> r.json()
{u'private_gists': 419, u'total_private_repos': 77, ...}

实现类似功能,urllib2模块要麻烦许多(注意,上面requests只用一句代码而已):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import urllib2
gh_url = 'https://api.github.com'
req = urllib2.Request(gh_url)
password_manager = urllib2.HTTPPasswordMgrWithDefault
Realm()
password_manager.add_password(None, gh_url, 'user', 'pas
s')
auth_manager = urllib2.HTTPBasicAuthHandler(password_m
anager)
opener = urllib2.build_opener(auth_manager)
urllib2.install_opener(opener)
handler = urllib2.urlopen(req)
print handler.getcode()
print handler.headers.getheader('content-type')
# ------
# 200
# 'application/json'

requests允许你发送纯粹的HTTP/1.1请求,无需额外的操作。也就是说不需要再ULR中添加额外的查询语句,或者对POST提交的数据进行编码。另外Keep-alive和HTTP连接池都是100%自动进行的。requests能怎么牛,多亏了urllib3的助攻

功能特性
requests完全满足当今web需求:
keep-Alive & 连接池
国际化域名和URLs
带Cookie的持久会话
浏览器式的SSL认证
内容自动解码
基本/摘要式身份验证
优雅的键/值 Cookie
自动解压
Unicode响应体
支持HTTP(S)代理
文件分块上传
流下载
连接超时
分块请求
支持 .netrc

Requests 正式支持 Python 2.6-2.7 和 Python 3.4-
3.7,并且在 PyPy 上可以很好的运行

Armin Ronacher——
requests诠释了什么才是完美的API

requests是Python所以模块中最受欢迎的一个。
Requests 是基于 PEP20为指导思想开发的:
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Readability counts.

Requests 发布协议为 Apache2 License
requests协议
Copyright 2017 Kenneth Reitz
Licensed under the Apache License, Version 2.0 (t
he “License”); you may not use this file except in c
ompliance with the License. You may obtain a cop
y of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in
writing, software distributed under the License is d
istributed on an “AS IS” BASIS, WITHOUT WARRA
NTIES OR CONDITIONS OF ANY KIND, either exp
ress or implied. See the License for the specific la
nguage governing permissions and limitations und
er the License.

安装requests

在终端运行安装命令
$ pipenv install requests

如果你没有安装pipenv,那么请先安装pipenv(pipenv是比pip更高级的工具,可简化依赖关系的管理,pip install pipenv进行安装);当然你也可以使用pip来安装。。。

获取源码
git公共仓获取:
$ git clone git://github.com/requests/requests.git
直接下载压缩包:
$ curl -OL https://github.com/requests/requests/tarball/master
windows用户可使用以下下载地址:
https://github.com/requests/requests/zipball/master

获取源码后你可以轻松将其安装到你的site-packages:

$ cd requests
$ pip install

快速上手

发送请求

例如尝试获取Github的公共时间轴:

>>> import requests
>>> r = requests.get('https://api.github.com/events')

现在我们得到一个response对象r。我们可以从这个对象中获取所想要的信息。

requests简便的API意味着所有HTTP请求类型都是显而易见的,例如,可以发送一个POST请求:

>>> r = requests.post('http://httpbin.org/post', data = {'key':'value'})

其他请求发送:

>>> r = requests.put('http://httpbin.org/put', data = {'key':'value'})
>>> r = requests.delete('http://httpbin.org/delete')
>>> r = requests.head('http://httpbin.org/get')
>>> r = requests.options('http://httpbin.org/get')

传递URL数据

我们经常需要通过URL的查询字符串传递某种数据,如果手工构建URL,那么数据是以键/值对的形式置于URL中的。例如,httpbin.org/get?key=val。

通过params 关键字参数requests允许你将这些数打包为一个字符串字典的形式传递,比如传递 key1=value1 和 key2=value2 参数到 httpbin.org/get 中:

>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.get("http://httpbin.org/get", params=payload)
>>> print(r.url)
http://httpbin.org/get?key2=value2&key1=value1

注意,字典里的值如果是None的键不会被添加到URL的查询字符串里。

可以将一个列表作为值传入,requests会自动帮你展开:

>>> payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
>>> r = requests.get('http://httpbin.org/get', params=payload)
>>> print(r.url)
http://httpbin.org/get?key1=value1&key2=value2&key2=value3

响应内容

读取服务器响应内容

>>> import requests
>>> r = requests.get('https://api.github.com/events')
>>> r.text
u'[{"repository":{"open_issues":0,"url":"https://github.com/...

requests会自动解码来自服务器的内容,大多数Unicode字符集都能被自动解码。
请求发出后,requests会对基于HTTP头部对响应的编码做出有根据的推测。当你访问r.text的时候,requests会使用其推测出来的文本编码进行解码。通过r.encoding属性可以查看requests使用了什么编码,也能自定义编码:

>>> r.encoding
'utf-8'
>>> r.encoding = 'ISO-8859-1'

可以使用一些特殊的计算获得编码值,比如HTTP和XML自身就可以指定编码,应该使用 r.content来获取编码,然后使用r.encoding 设置相应的编码值。这样就能使用正确的编码来解析 r.text 了。

二进制响应内容

你也能以字节方式访问响应的内容,对于非文本请求:

>>> r.content
b'[{"repository":{"open_issues":0,"url":"https://github.com/...

requests 会自动为你解码 gzip 和 deflate传输编码(为提高效率,很多服务器将内容进行压缩后传输)的响应。

例如,从服务器返回的二进制数据中创建一张图片:

>>> from PIL import Image
>>> from io import BytesIO
>>> i = Image.open(BytesIO(r.content))

JSON响应内容

requests内置JSON解码器,可以处理JSON格式的数据:

>>> import requests
>>> r = requests.get('https://api.github.com/events')
>>> r.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...

注意,成功调用r.json()并不意味着就是响应成功了。因为有的服务器会在失败的响应中包含一个JSON对象(比如HTTP 500的错误细节),这种JSON同样会被解码后返回。所以要检查发送的请求是否成功,请使用r.raise_for_status()函数或者检查 r.status_code的值。

原始响应内容

获取来自服务器的原始套接字响应信息:

>>> r = requests.get('https://api.github.com/events', stream=True)
>>> r.raw
<requests.packages.urllib3.response.HTTPResponse object at 0x101194810>
>>> r.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=128):
		fd.write(chunk)

Response.iter_content 将会帮你处理大量由于直接使用 Response.raw 而不得不处理的内容。当使用流下载时,我们推荐使用上面代码来获取内容。注意根据实际情况设置chunk_size。

自定义请求头headers

例如指定user-agent:

>>> url = 'https://api.github.com/some/endpoint'
>>> headers = {'user-agent': 'my-app/0.0.1'}
>>> r = requests.get(url, headers=headers)

定制headers的优先级低于某些特定的信息源,例如:
如果在.netrc中设置了用户认证信息,使用headers=设置的授权就不会生效。而如果设置了auth=参数,.netrc的设置就无效了。
如果被重定向到别的主机,header的授权就会被删除。header代理授权会被URL中提供的代理身份覆盖掉。在我们能判断内容长度的情况下,header的Conten-Length会被改写。

更复杂的POST请求

发送编码为表单形式的数据——比如HTML表单。添加data参数,数据字典在发出请求时就会自动编码为表单形式:

>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post("http://httpbin.org/post", data=payloa
d)
>>> print(r.text)
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}

还可以为data参数传入一个元组列表,表单中一个key对应多个value时,此种方式尤其有效:

>>> payload = (('key1', 'value1'), ('key1', 'value2'))
>>> r = requests.post('http://httpbin.org/post', data=payload
)
>>> print(r.text)
{
...
"form": {
"key1": [
"value1",
"value2"
]
},
...
}

很多时候你想要发送的数据并非表单形式的编码。如果你传递一个string而非dict,那么数据会被直接发送出去。
例如,GitHub API v3接受编码为JSON 的 POST/PATCH 数据:

>>> import json
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, data=json.dumps(payload))

除了可自己对dict进行编码,你还可以使用json参数直接传递数据,他将被自动编码(requests2.4.2版本新增特性):

>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, json=payload)

POST多部分编码的(Multipart-Encoded)文件

requests使得上传多部分编码变得简单:

>>> url = 'http://httpbin.org/post'
>>> files = {'file': open('report.xls', 'rb')}
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": ""
},
...
}

你可以显示的设置文件名、文件类型和请求头:

>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'applicat
ion/vnd.ms-excel', {'Expires': '0'})}
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": ""
},
...
}

还可以发送作为文件来接收的字符串:

>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.csv', 'some,data,to,send\nanother,r
ow,to,send\n')}
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": "some,data,to,send\\nanother,row,to,send\\n"
},
...
}

转自:鱼C论坛
作者:小甲鱼
链接(手机端):http://wsq.discuz.com/?siteid=260689727&c=index&a=viewthread&tid=95893&mobile=2


你可能感兴趣的:(Python)