我忍了这个库好久了,都懒得总结,只会常用的结果方法。但是作为人类的结晶,作为python 众多模块的佼佼者,那就必须吃定她了
github : star 40K+ (可以说很牛逼的存在了)
- 5,923次 提交
- 137个 发布
-
553位 贡献者
正如他的宣言:简单而优雅
简单了解:
>>> 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, ...}
***********************************************************************
简单说一下 urllib urllib2 urllib3 requests
python2 里面有 urllib 和urllib2
python3 把这两个合并为urllib
而 urllib3 和requests 是第三方库,并且requests 是对urllib3 的封装
回忆一下 ulrlib2 的使用方法(python2 中使用) 简单了解一下:
urllib2提供了Request该类,该类可以提供更多功能
r = Request(url='http://www.mysite.com')
r.add_header('User-Agent', 'awesome fetcher')
r.add_data(urllib.urlencode({'foo': 'bar'})
response = urlopen(r)
# 请注意,urlencode()仅在urllib中,而不在urllib2中,因为 请求前肯定要是对url进行编码
# urllib提供了urlencode方法,该方法用于生成GET查询字符串,而urllib2没有
这种功能。这是urllib与urllib2经常一起使用的原因之一
其实现在python3 整合了 urllib 和 urllib2 为 urllib (这里并不是 urllib3 因为urllib3 是第三方库)
-
urllib3
Urllib3是一个功能强大,条理清晰,用于HTTP客户端的Python库。许多Python的原生系统已经开始使用urllib3。Urllib3提供了很多python标准库urllib里所没有的重要特性
urllib3 简单使用(使用前先安装哦):
pip install urllib3
- 简单使用()
>>> import urllib3
>>> http = urllib3.PoolManager() # urllib3主要使用连接池进行网络请求的访
# 问,所以访问之前我们需要创建一个连接池对象
>>> r = http.request('GET', 'http://httpbin.org/robots.txt')
>>> r.status
200
>>> r.data
'User-agent: *\nDisallow: /deny\n'
- 设置headers
headers={'X-Something': 'value'}
resp = http.request('GET', 'http://httpbin.org/headers', headers=headers)
- 设置url参数
fields = {'arg': 'value'}
resp = http.request('GET', 'http://httpbin.org/get', fields=fields)
如果使用的是POST等方法,则会将fields作为请求的请求正文发送
也就是说 如果想用post 传url 参数,只能自己事先写好穿进去。
- 设置代理
>>> import urllib3
>>> proxy = urllib3.ProxyManager('http://50.233.137.33:80', headers=
{'connection': 'keep-alive'})
>>> resp = proxy.request('get', 'http://httpbin.org/ip')
>>> resp.status
200
>>> resp.data
b'{"origin":"50.233.136.254"}\n'
***************************************************************
讲完了urllib3
下面切入正题 requests:
-
requests
注:主要来自于官方文档 ,比较详细了
-
快速入门
请求:
当然最常见的就是get 和 post 了
r = requests.put('https://httpbin.org/put', data = {'key':'value'})
r = requests.delete('https://httpbin.org/delete')
r = requests.head('https://httpbin.org/get')
r = requests.options('https://httpbin.org/get')
r = requests.post('https://httpbin.org/post', data = {'key':'value'})
r = requests.get('https://api.github.com/events')
传递参数
-
params 参数:查询字符串的形式:
这个比较简单
请求的url直接编写
httpbin.org/get?key=val 像这样
或者是传递参数
payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
r = requests.get('https://httpbin.org/get', params=payload)
print(r.url)
https://httpbin.org/get?key1=value1&key2=value2&key2=value3
列表对应的参数会编码成统一个key,就是一个key 对应多个值的情况
-
data 参数:请求体传参,常见于post方式:
请求体参数是传给 data 关键字参数
字典将自动进行表单编码
>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post("https://httpbin.org/post", data=payload)
>>> print(r.text)
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
对于data单键多值的情况,可以这样做
这有时候特别有用
1 、 创建data元组列表
>>> payload_tuples = [('key1', 'value1'), ('key1', 'value2')]
>>> r1 = requests.post('https://httpbin.org/post', data=payload_tuples)
2 、 将列表作为值的字典
>>> payload_dict = {'key1': ['value1', 'value2']}
>>> r2 = requests.post('https://httpbin.org/post', data=payload_dict)
上面两个传参的形式结果都是:
>>> print(r1.text)
{
...
"form": {
"key1": [
"value1",
"value2"
]
},
...
}
>>> r1.text == r2.text
True
data 参数的格式:
其实可以直接发送string 格式的数据:
>>> import json
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, data=json.dumps(payload))
-
json 参数:也算是请求体:
和data类似。但是会默认 把请求头参数 Content-Type设置为application/json
注意:如果同时传入了data 或者 files,json 将成砖头,自动忽略掉 - files 参数:上传文件:
>>> url = 'https://httpbin.org/post'
>>> files = {'file': open('report.xls', 'rb')}
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": "<censored...binary...data>"
},
...
}
# 显式设置文件名,content_type和标头(这些就要用元祖传递了,顺序应该也是固定的哦)
files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel',
{'Expires': '0'})}
然后传给request
其实文件也可以是字符串啦:
files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}.
文件上传 流式传输
requests 默认不支持流传输,但是官方推荐了另外一个包:
但是有一个单独的软件包可以 requests-toolbelt
。您应该阅读文档,以获取有关如何使用它的更多详细信息。
-
请求头参数 headers
headers 是一个dict
后面再说
>>> url = 'https://api.github.com/some/endpoint'
>>> headers = {'user-agent': 'my-app/0.0.1'}
>>> r = requests.get(url, headers=headers)
响应:
-
响应体:
文本格式 r.text:
默认编码格式设置为 响应头里面传过来的,当然你也可以在 .text 之前设置 自
定义的编码格式:
>>> r.encoding # 获取编码格式
'utf-8'
>>> r.encoding = 'ISO-8859-1' # 设置编码格式
当你调用 .text 的时候,会动态读取当前的 r.encoding,然后返回响应数据unicode(字节码)对应的解码内容,是不是很人性化的
其实 .text 内部 也是先运行 。content ,然后在进行解码的
二进制格式 r.content:
例如图片和zip等,最好用content ,便于后面写入文件操作
>>> from PIL import Image
>>> from io import BytesIO
>>> i = Image.open(BytesIO(r.content))
>> i.show() # 显示图片
# Image.open我还记得,好像是图片对象,做毕设的时候好像用过
json 格式 r.json():
如果 json格式解码失败,报错:ValueError: No JSON object could be decoded
其实这个方法也是调用内置的 json.loads() 。
注意的是,有时候失败也会返回json 格式的字符串(例如HTTP 500的错误详细信息),所以这个不能是判断响应成功的根据。使用r.status_code 来判断更为确切啦啦啦
原始套接字内容 r.raw (好像是个httpresponse 对象啊)
但是有个前提 就是 请求的时候设置了 stream=True
>>> r = requests.get('https://api.github.com/events', stream=True)
>>> r.raw
<urllib3.response.HTTPResponse object at 0x101194810>
>>> r.raw.read(10)
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
对于直接流传输的 r.iter_content 本地流式接收数据可以这样:
with open(filename, 'wb') as fd:
for chunk in r.iter_content(chunk_size=128):
fd.write(chunk)
r.iter_content vs r,raw
iter_content 会自动解码gzip和deflate 传输编码,而raw 不会
-
响应状态码 r.status_code
>>> r.status_code
200
# 带有内置状态标记,防止你记不住折磨多状态码,那些是ok 的
>>> r.status_code == requests.codes.ok
True
# 还有一个函数来抛出异常,这个就太细致了
>>> bad_r.status_code
404
>>> bad_r.raise_for_status()
Traceback (most recent call last):
File "requests/models.py", line 832, in raise_for_status
raise http_error
requests.exceptions.HTTPError: 404 Client Error
如果你的status_code 是200 这种,那就返回none
>>> r.raise_for_status()
None
-
响应头 r.headers
>>> r.headers
{
'content-encoding': 'gzip',
'transfer-encoding': 'chunked',
'connection': 'close',
'server': 'nginx/1.0.4',
'x-runtime': '148ms',
'etag': '"e1ca502697e5c9317743dc078f67693f"',
'content-type': 'application/json'
}
但是这个字典有点特殊
r.headers['Content-Type'] 和 r.headers.get('content-type') 都能取到值
-
r.cookie
>>> r.cookies['example_cookie_name']
'example_cookie_value'
要将自己的cookie发送到服务器,可以使用以下cookies 参数:
>>> url = 'https://httpbin.org/cookies'
>>> cookies = dict(cookies_are='working')
>>> r = requests.get(url, cookies=cookies)
>>> r.text
'{"cookies": {"cookies_are": "working"}}'
-
重定向和历史
pass 吧
-
超时
指定的秒数后停止等待响应,这个以前没注意,现在看来是一个必传参数了。
因为没有这个超时参数,有可能造成程序不停止:
几乎所有生产代码都应在几乎所有请求中使用此参数。否则,可能会导致程序无限期挂起 ——官方的原话
几秒钟timeout内未在基础套接字上接收到任何字节,则会引发异常timeout
-
错误和异常
网络问题(例如DNS故障,连接被拒绝等),请求将引发ConnectionError异常
返回的状态码失败 则引发 HTTPError
超时错误:Timeout则会引发异常
请求超过配置的最大重定向数 : TooManyRedirects
异常都继承自 requests.exceptions.RequestException
至此,已经大致学习了,requests 最常见的内容
高级用法
:包含很多问题解决方法
认证方式
先把认证搞一下,高级教程,以后出问题的时候直接查询官方文档算了,因为东西实在是too much 了
-
基本身份认证(就是用户名密码):
>>> from requests.auth import HTTPBasicAuth
>>> requests.get('https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))
<Response [200]>
或者简写为:
>> requests.get('https://api.github.com/user', auth=('user', 'pass'))
<Response [200]>
和上面的效果是一样的哦
-
netrc认证
pass
-
摘要式身份验证
HTTP身份验证的另一种非常流行的形式是摘要身份验证,并且Requests也支持此功能
>>> from requests.auth import HTTPDigestAuth
>>> url = 'https://httpbin.org/digest-auth/auth/user/pass'
>>> requests.get(url, auth=HTTPDigestAuth('user', 'pass'))
<Response [200]>
-
OAuth 1身份验证
OAuth是几种Web API的常见身份验证形式。该requests-oauthlib 库允许“请求”用户轻松进行OAuth 1身份验证的请求
>>> import requests
>>> from requests_oauthlib import OAuth1
>>> url = 'https://api.twitter.com/1.1/account/verify_credentials.json'
>>> auth = OAuth1('YOUR_APP_KEY', 'YOUR_APP_SECRET',
... 'USER_OAUTH_TOKEN', 'USER_OAUTH_TOKEN_SECRET')
>>> requests.get(url, auth=auth)
<Response [200]>
-
OAuth 2和OpenID Connect身份验证
pass
-
其他认证
pass
说实话,除了第一种用户名密码,其他的看不懂,哈哈哈
*******************************************************
这里附上 所有请求方式的方法都要调用的 request 方法(很像urllib3的
urllib3.PoolManager().request(method,url,[...]))
def request(method, url, **kwargs):
"""Constructs and sends a :class:`Request <Request>`.
:param method: method for the new :class:`Request` object
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary, list of tuples or bytes to send
in the body of the :class:`Request`.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
:param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
to add for the file.
:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
:param timeout: (optional) How many seconds to wait for the server to send data
before giving up, as a float, or a :ref:`(connect timeout, read
timeout) <timeouts>` tuple.
:type timeout: float or tuple
:param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to
``True``.
:type allow_redirects: bool
:param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
:param verify: (optional) Either a boolean, in which case it controls whether we verify
the server's TLS certificate, or a string, in which case it must be a path
to a CA bundle to use. Defaults to ``True``.
:param stream: (optional) if ``False``, the response content will be immediately downloaded.
:param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
:return: :class:`Response <Response>` object
:rtype: requests.Response
Usage::
>>> import requests
>>> req = requests.request('GET', 'https://httpbin.org/get')
<Response [200]>
"""
# By using the 'with' statement we are sure the session is closed, thus we
# avoid leaving sockets open which can trigger a ResourceWarning in some
# cases, and look like a memory leak in others.
with sessions.Session() as session:
return session.request(method=method, url=url, **kwargs)
# requests.post 源码
def post(url, data=None, json=None, **kwargs):
r"""Sends a POST request.
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) json data to send in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
"""
return request('post', url, data=data, json=json, **kwargs)
网友评论