美文网首页
python requests 大法 牛逼

python requests 大法 牛逼

作者: 天空蓝雨 | 来源:发表于2020-01-03 09:54 被阅读0次

我忍了这个库好久了,都懒得总结,只会常用的结果方法。但是作为人类的结晶,作为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)

相关文章

网友评论

      本文标题:python requests 大法 牛逼

      本文链接:https://www.haomeiwen.com/subject/pycmnctx.html