• 转:Python requests 快速入门


    迫不及待了吗?本页内容为如何入门Requests提供了很好的指引。其假设你已经安装了Requests。如果还没有, 去 安装 一节看看吧。

    首先,确认一下:

    ·Requests 已安装

    ·Requests是 最新的

    让我们从一些简单的示例开始吧。

    发送请求

    使用Requests发送网络请求非常简单。

    一开始要导入Requests模块:

    >>> import requests

    然后,尝试获取某个网页。本例子中,我们来获取Github的公共时间线

    >>> r = requests.get('https://github.com/timeline.json')

    现在,我们有一个名为 r 的 Response 对象。可以从这个对象中获取所有我们想要的信息。

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

    >>> r = requests.post("http://httpbin.org/post")

    漂亮,对吧?那么其他HTTP请求类型:PUT, DELETE, HEAD以及OPTIONS又是如何的呢?都是一样的简单:

    >>> r = requests.put("http://httpbin.org/put")

    >>> r = requests.delete("http://httpbin.org/delete")

    >>> r = requests.head("http://httpbin.org/get")

    >>> r = requests.options("http://httpbin.org/get")

    都很不错吧,但这也仅是Requests的冰山一角呢。

    为URL传递参数

    你也许经常想为URL的查询字符串(query string)传递某种数据。如果你是手工构建URL,那么数据会以键/值 对的形式置于URL中,跟在一个问号的后面。例如,httpbin.org/get?key=val 。 Requests允许你使用 params 关键字参数,以一个字典来提供这些参数。举例来说,如果你想传递 key1=value1 和 key2=value2 到 httpbin.org/get ,那么你可以使用如下代码:

    >>> payload = {'key1': 'value1', 'key2': 'value2'}

    >>> r = requests.get("http://httpbin.org/get", params=payload)

    通过打印输出该URL,你能看到URL已被正确编码:

    >>> print r.url

    u'http://httpbin.org/get?key2=value2&key1=value1'

    响应内容

    我们能读取服务器响应的内容。再次以Github时间线为例:

    >>> import requests

    >>> r = requests.get('https://github.com/timeline.json')

    >>> r.text

    '[{"repository":{"open_issues":0,"url":"https://github.com/...

    Requests会自动解码来自服务器的内容。大多数unicode字符集都能被无缝地解码。

    请求发出后,Requests会基于HTTP头部对响应的编码作出有根据的推测。当你访问r.text 之时,Requests会使用其推测的文本编码。你可以找出Requests使用了什么编码,并且能够使用 r.encoding 属性来改变它:

    >>> r.encoding

    'utf-8'

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

    如果你改变了编码,每当你访问 r.text ,Request都将会使用 r.encoding 的新值。

    在你需要的情况下,Requests也可以使用定制的编码。如果你创建了自己的编码,并使用codecs 模块进行注册,你就可以轻松地使用这个解码器名称作为 r.encoding 的值, 然后由Requests来为你处理编码。

    二进制响应内容

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

    >>> r.content

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

    Requests会自动为你解码 gzip 和 deflate 传输编码的响应数据。

    例如,以请求返回的二进制数据创建一张图片,你可以使用如下代码:

    >>> from PIL import Image

    >>> from StringIO import StringIO

    >>> i = Image.open(StringIO(r.content))

    JSON响应内容

    Requests中也有一个内置的JSON解码器,助你处理JSON数据:

    >>> import requests

    >>> r = requests.get('https://github.com/timeline.json')

    >>> r.json()

    [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...

    如果JSON解码失败, r.json 就会抛出一个异常。

    原始响应内容

    在罕见的情况下你可能想获取来自服务器的原始套接字响应,那么你可以访问 r.raw 。 如果你确实想这么干,那请你确保在初始请求中设置了 stream=True 。具体的你可以这么做:

    >>> r = requests.get('https://github.com/timeline.json', stream=True)

    >>> r.raw

    <requests.packages.urllib3.response.HTTPResponse object at 0x101194810>

    >>> r.raw.read(10)

    'x1fx8bx08x00x00x00x00x00x00x03'

    定制请求头

    如果你想为请求添加HTTP头部,只要简单地传递一个 dict 给 headers 参数就可以了。

    例如,在前一个示例中我们没有指定content-type:

    >>> import json

    >>> url = 'https://api.github.com/some/endpoint'

    >>> payload = {'some': 'data'}

    >>> headers = {'content-type': 'application/json'}

    >>> r = requests.post(url, data=json.dumps(payload), headers=headers)

    更加复杂的POST请求

    通常,你想要发送一些编码为表单形式的数据—非常像一个HTML表单。 要实现这个,只需简单地传递一个字典给 data 参数。你的数据字典 在发出请求时会自动编码为表单形式:

    >>> payload = {'key1': 'value1', 'key2': 'value2'}

    >>> r = requests.post("http://httpbin.org/post", data=payload)

    >>> print r.text

    {

      ...

      "form": {

        "key2": "value2",

        "key1": "value1"

      },

      ...

    }

    很多时候你想要发送的数据并非编码为表单形式的。如果你传递一个 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))

    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": "<censored...binary...data>"

      },

      ...

    }

    你可以显式地设置文件名:

    >>> url = 'http://httpbin.org/post'

    >>> files = {'file': ('report.xls', open('report.xls', 'rb'))}

    >>> r = requests.post(url, files=files)

    >>> r.text

    {

      ...

      "files": {

        "file": "<censored...binary...data>"

      },

      ...

    }

    如果你想,你也可以发送作为文件来接收的字符串:

    >>> url = 'http://httpbin.org/post'

    >>> files = {'file': ('report.csv', 'some,data,to,send another,row,to,send ')}

    >>> r = requests.post(url, files=files)

    >>> r.text

    {

      ...

      "files": {

        "file": "some,data,to,send\nanother,row,to,send\n"

      },

      ...

    }

    响应状态码

    我们可以检测响应状态码:

    >>> r = requests.get('http://httpbin.org/get')

    >>> r.status_code

    200

    为方便引用,Requests还附带了一个内置的状态码查询对象:

    >>> r.status_code == requests.codes.ok

    True

    如果发送了一个失败请求(非200响应),我们可以通过 Response.raise_for_status() 来抛出异常:

    >>> bad_r = requests.get('http://httpbin.org/status/404')

    >>> 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

    但是,由于我们的例子中 r 的 status_code 是 200 ,当我们调用 raise_for_status() 时,得到的是:

    >>> r.raise_for_status()

    None

    一切都挺和谐哈。

    响应头

    我们可以查看以一个Python字典形式展示的服务器响应头:

    >>> r.headers

    {

        'status': '200 OK',

        'content-encoding': 'gzip',

        'transfer-encoding': 'chunked',

        'connection': 'close',

        'server': 'nginx/1.0.4',

        'x-runtime': '148ms',

        'etag': '"e1ca502697e5c9317743dc078f67693f"',

        'content-type': 'application/json; charset=utf-8'

    }

    但是这个字典比较特殊:它是仅为HTTP头部而生的。根据 RFC 2616 , HTTP头部是大小写不敏感的。

    因此,我们可以使用任意大写形式来访问这些响应头字段:

    >>> r.headers['Content-Type']

    'application/json; charset=utf-8'

    >>> r.headers.get('content-type')

    'application/json; charset=utf-8'

    如果某个响应头字段不存在,那么它的默认值为 None

    >>> r.headers['X-Random']

    None

    Cookies

    如果某个响应中包含一些Cookie,你可以快速访问它们:

    >>> url = 'http://example.com/some/cookie/setting/url'

    >>> r = requests.get(url)

    >>> r.cookies['example_cookie_name']

    'example_cookie_value'

    要想发送你的cookies到服务器,可以使用 cookies 参数:

    >>> url = 'http://httpbin.org/cookies'

    >>> cookies = dict(cookies_are='working')

    >>> r = requests.get(url, cookies=cookies)

    >>> r.text

    '{"cookies": {"cookies_are": "working"}}'

    重定向与请求历史

    使用GET或OPTIONS时,Requests会自动处理位置重定向。

    Github将所有的HTTP请求重定向到HTTPS。可以使用响应对象的 history 方法来追踪重定向。 我们来看看Github做了什么:

    >>> r = requests.get('http://github.com')

    >>> r.url

    'https://github.com/'

    >>> r.status_code

    200

    >>> r.history

    [<Response [301]>]

    Response.history 是一个:class:Request 对象的列表,为了完成请求而创建了这些对象。这个对象列表按照从最老到最近的请求进行排序。

    如果你使用的是GET或OPTIONS,那么你可以通过 allow_redirects 参数禁用重定向处理:

    >>> r = requests.get('http://github.com', allow_redirects=False)

    >>> r.status_code

    301

    >>> r.history

    []

    如果你使用的是POST,PUT,PATCH,DELETE或HEAD,你也可以启用重定向:

    >>> r = requests.post('http://github.com', allow_redirects=True)

    >>> r.url

    'https://github.com/'

    >>> r.history

    [<Response [301]>]

    超时

    你可以告诉requests在经过以 timeout 参数设定的秒数时间之后停止等待响应:

    >>> requests.get('http://github.com', timeout=0.001)

    Traceback (most recent call last):

      File "<stdin>", line 1, in <module>

    requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)

    注:

    timeout 仅对连接过程有效,与响应体的下载无关。

    错误与异常

    遇到网络问题(如:DNS查询失败、拒绝连接等)时,Requests会抛出一个ConnectionError 异常。

    遇到罕见的无效HTTP响应时,Requests则会抛出一个 HTTPError 异常。

    若请求超时,则抛出一个 Timeout 异常。

    若请求超过了设定的最大重定向次数,则会抛出一个 TooManyRedirects 异常。

    所有Requests显式抛出的异常都继承requests.exceptions.RequestException 。

    高级用法

    本篇文档涵盖了Requests的一些更加高级的特性。

    会话对象

    会话对象让你能够跨请求保持某些参数。它也会在同一个Session实例发出的所有请求之间保持cookies。

    会话对象具有主要的Requests API的所有方法。

    我们来跨请求保持一些cookies:

    s = requests.Session()

    s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')

    r = s.get("http://httpbin.org/cookies")

    print r.text

    # '{"cookies": {"sessioncookie": "123456789"}}'

    会话也可用来为请求方法提供缺省数据。这是通过为会话对象的属性提供数据来实现的:

    s = requests.Session()

    s.auth = ('user', 'pass')

    s.headers.update({'x-test': 'true'})

    # both 'x-test' and 'x-test2' are sent

    s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})

    任何你传递给请求方法的字典都会与已设置会话层数据合并。方法层的参数覆盖会话的参数。

    从字典参数中移除一个值

    有时你会想省略字典参数中一些会话层的键。要做到这一点,你只需简单地在方法层参数中将那个键的值设置为 None ,那个键就会被自动省略掉。

    包含在一个会话中的所有数据你都可以直接使用。学习更多细节请阅读 会话API文档 。

    请求与响应对象

    任何时候调用requests.*()你都在做两件主要的事情。其一,你在构建一个 Request 对象, 该对象将被发送到某个服务器请求或查询一些资源。其二,一旦 requests 得到一个从 服务器返回的响应就会产生一个 Response 对象。该响应对象包含服务器返回的所有信息, 也包含你原来创建的 Request 对象。如下是一个简单的请求,从Wikipedia的服务器得到 一些非常重要的信息:

    >>> r = requests.get('http://en.wikipedia.org/wiki/Monty_Python')

    如果想访问服务器返回给我们的响应头部信息,可以这样做:

    >>> r.headers

    {'content-length': '56170', 'x-content-type-options': 'nosniff', 'x-cache':

    'HIT from cp1006.eqiad.wmnet, MISS from cp1010.eqiad.wmnet', 'content-encoding':

    'gzip', 'age': '3080', 'content-language': 'en', 'vary': 'Accept-Encoding,Cookie',

    'server': 'Apache', 'last-modified': 'Wed, 13 Jun 2012 01:33:50 GMT',

    'connection': 'close', 'cache-control': 'private, s-maxage=0, max-age=0,

    must-revalidate', 'date': 'Thu, 14 Jun 2012 12:59:39 GMT', 'content-type':

    'text/html; charset=UTF-8', 'x-cache-lookup': 'HIT from cp1006.eqiad.wmnet:3128,

    MISS from cp1010.eqiad.wmnet:80'}

    然而,如果想得到发送到服务器的请求的头部,我们可以简单地访问该请求,然后是该请求的头部:

    >>> r.request.headers

    {'Accept-Encoding': 'identity, deflate, compress, gzip',

    'Accept': '*/*', 'User-Agent': 'python-requests/0.13.1'}

    SSL证书验证

    Requests可以为HTTPS请求验证SSL证书,就像web浏览器一样。要想检查某个主机的SSL证书,你可以使用 verify 参数:

    >>> requests.get('https://kennethreitz.com', verify=True)

    requests.exceptions.SSLError: hostname 'kennethreitz.com' doesn't match either of '*.herokuapp.com', 'herokuapp.com'

    在该域名上我没有设置SSL,所以失败了。但Github设置了SSL:

    >>> requests.get('https://github.com', verify=True)

    <Response [200]>

    对于私有证书,你也可以传递一个CA_BUNDLE文件的路径给 verify 。你也可以设置REQUEST_CA_BUNDLE 环境变量。

    如果你将 verify 设置为False,Requests也能忽略对SSL证书的验证。

    >>> requests.get('https://kennethreitz.com', verify=False)

    <Response [200]>

    默认情况下, verify 是设置为True的。选项 verify 仅应用于主机证书。

    你也可以指定一个本地证书用作客户端证书,可以是单个文件(包含密钥和证书)或一个包含两个文件路径的元组:

    >>> requests.get('https://kennethreitz.com', cert=('/path/server.crt', '/path/key'))

    <Response [200]>

    如果你指定了一个错误路径或一个无效的证书:

    >>> requests.get('https://kennethreitz.com', cert='/wrong_path/server.pem')

    SSLError: [Errno 336265225] _ssl.c:347: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib

    响应体内容工作流

    默认情况下,当你进行网络请求后,响应体会立即被下载。你可以通过 stream 参数覆盖这个行为,推迟下载响应体直到访问 Response.content 属性:

    tarball_url = 'https://github.com/kennethreitz/requests/tarball/master'

    r = requests.get(tarball_url, stream=True)

    此时仅有响应头被下载下来了,连接保持打开状态,因此允许我们根据条件获取内容:

    if int(r.headers['content-length']) < TOO_LONG:

      content = r.content

      ...

    你可以进一步使用 Response.iter_content 和 Response.iter_lines 方法来控制工作流,或者以 Response.raw 从底层urllib3的 urllib3.HTTPResponse 读取。

    保持活动状态(持久连接)

    好消息 - 归功于urllib3,同一会话内的持久连接是完全自动处理的!同一会话内你发出的任何请求都会自动复用恰当的连接!

    注意:只有所有的响应体数据被读取完毕连接才会被释放为连接池;所以确保将 stream设置为 False 或读取 Response 对象的 content 属性。

    流式上传

    Requests支持流式上传,这允许你发送大的数据流或文件而无需先把它们读入内存。要使用流式上传,仅需为你的请求体提供一个类文件对象即可:

    with open('massive-body') as f:

        requests.post('http://some.url/streamed', data=f)

    块编码请求

    对于出去和进来的请求,Requests也支持分块传输编码。要发送一个块编码的请求,仅需为你的请求体提供一个生成器(或任意没有具体长度(without a length)的迭代器):

    def gen():

        yield 'hi'

        yield 'there'

    requests.post('http://some.url/chunked', data=gen())

    事件挂钩

    Requests有一个钩子系统,你可以用来操控部分请求过程,或信号事件处理。

    可用的钩子:

    response:

    从一个请求产生的响应

    你可以通过传递一个 {hook_name: callback_function} 字典给 hooks 请求参数 为每个请求分配一个钩子函数:

    hooks=dict(response=print_url)

    callback_function 会接受一个数据块作为它的第一个参数。

    def print_url(r):

        print(r.url)

    若执行你的回调函数期间发生错误,系统会给出一个警告。

    若回调函数返回一个值,默认以该值替换传进来的数据。若函数未返回任何东西, 也没有什么其他的影响。

    我们来在运行期间打印一些请求方法的参数:

    >>> requests.get('http://httpbin.org', hooks=dict(response=print_url))

    http://httpbin.org

    <Response [200]>

    自定义身份验证

    Requests允许你使用自己指定的身份验证机制。

    任何传递给请求方法的 auth 参数的可调用对象,在请求发出之前都有机会修改请求。

    自定义的身份验证机制是作为 requests.auth.AuthBase 的子类来实现的,也非常容易定义。

    Requests在 requests.auth 中提供了两种常见的的身份验证方案: HTTPBasicAuth 和HTTPDigestAuth 。

    假设我们有一个web服务,仅在 X-Pizza 头被设置为一个密码值的情况下才会有响应。虽然这不太可能, 但就以它为例好了

    from requests.auth import AuthBase

    class PizzaAuth(AuthBase):

        """Attaches HTTP Pizza Authentication to the given Request object."""

        def __init__(self, username):

            # setup any auth-related data here

            self.username = username

        def __call__(self, r):

            # modify and return the request

            r.headers['X-Pizza'] = self.username

            return r

    然后就可以使用我们的PizzaAuth来进行网络请求:

    >>> requests.get('http://pizzabin.org/admin', auth=PizzaAuth('kenneth'))

    <Response [200]>

    流式请求

    使用 requests.Response.iter_lines() 你可以很方便地对流式API(例如 Twitter的流式API )进行迭代。

    使用Twitter流式API来追踪关键字“requests”:

    import requests

    import json

    r = requests.post('https://stream.twitter.com/1/statuses/filter.json',

        data={'track': 'requests'}, auth=('username', 'password'), stream=True)

    for line in r.iter_lines():

        if line: # filter out keep-alive new lines

            print json.loads(line)

    代理

    如果需要使用代理,你可以通过为任意请求方法提供 proxies 参数来配置单个请求:

    import requests

    proxies = {

      "http": "http://10.10.1.10:3128",

      "https": "http://10.10.1.10:1080",

    }

    requests.get("http://example.org", proxies=proxies)

    你也可以通过环境变量 HTTP_PROXY 和 HTTPS_PROXY 来配置代理。

    $ export HTTP_PROXY="http://10.10.1.10:3128"

    $ export HTTPS_PROXY="http://10.10.1.10:1080"

    $ python

    >>> import requests

    >>> requests.get("http://example.org")

    若你的代理需要使用HTTP Basic Auth,可以使用 http://user:password@host/ 语法:

    proxies = {

        "http": "http://user:pass@10.10.1.10:3128/",

    }

    合规性

    Requests符合所有相关的规范和RFC,这样不会为用户造成不必要的困难。但这种对规范的考虑 导致一些行为对于不熟悉相关规范的人来说看似有点奇怪。

    编码方式

    当你收到一个响应时,Requests会猜测响应的编码方式,用于在你调用 Response.text 方法时 对响应进行解码。Requests首先在HTTP头部检测是否存在指定的编码方式,如果不存在,则会使用 charade 来尝试猜测编码方式。

    只有当HTTP头部不存在明确指定的字符集,并且 Content-Type 头部字段包含 text 值之时, Requests才不去猜测编码方式。

    在这种情况下, RFC 2616 指定默认字符集 必须是 ISO-8859-1 。Requests遵从这一规范。如果你需要一种不同的编码方式,你可以手动设置 Response.encoding 属性,或使用原始的 Response.content 。

    HTTP动词

    Requests提供了几乎所有HTTP动词的功能:GET,OPTIONS, HEAD,POST,PUT,PATCH和DELETE。 以下内容为使用Requests中的这些动词以及Github API提供了详细示例。

    我将从最常使用的动词GET开始。HTTP GET是一个幂等的方法,从给定的URL返回一个资源。因而, 当你试图从一个web位置获取数据之时,你应该使用这个动词。一个使用示例是尝试从Github上获取 关于一个特定commit的信息。假设我们想获取Requests的commit a050faf 的信息。我们可以 这样去做:

    >>> import requests

    >>> r = requests.get('https://api.github.com/repos/kennethreitz/requests/git/commits/a050faf084662f3a352dd1a941f2c7c9f886d4ad')

    我们应该确认Github是否正确响应。如果正确响应,我们想弄清响应内容是什么类型的。像这样去做:

    >>> if (r.status_code == requests.codes.ok):

    ...     print r.headers['content-type']

    ...

    application/json; charset=utf-8

    可见,GitHub返回了JSON数据,非常好,这样就可以使用 r.json 方法把这个返回的数据解析成Python对象。

    >>> commit_data = r.json()

    >>> print commit_data.keys()

    [u'committer', u'author', u'url', u'tree', u'sha', u'parents', u'message']

    >>> print commit_data[u'committer']

    {u'date': u'2012-05-10T11:10:50-07:00', u'email': u'me@kennethreitz.com', u'name': u'Kenneth Reitz'}

    >>> print commit_data[u'message']

    makin' history

    到目前为止,一切都非常简单。嗯,我们来研究一下GitHub的API。我们可以去看看文档, 但如果使用Requests来研究也许会更有意思一点。我们可以借助Requests的OPTIONS动词来看看我们刚使用过的url 支持哪些HTTP方法。

    >>> verbs = requests.options(r.url)

    >>> verbs.status_code

    500

    额,这是怎么回事?毫无帮助嘛!原来GitHub,与许多API提供方一样,实际上并未实现OPTIONS方法。 这是一个恼人的疏忽,但没关系,那我们可以使用枯燥的文档。然而,如果GitHub正确实现了OPTIONS, 那么服务器应该在响应头中返回允许用户使用的HTTP方法,例如

    >>> verbs = requests.options('http://a-good-website.com/api/cats')

    >>> print verbs.headers['allow']

    GET,HEAD,POST,OPTIONS

    转而去查看文档,我们看到对于提交信息,另一个允许的方法是POST,它会创建一个新的提交。 由于我们正在使用Requests代码库,我们应尽可能避免对它发送笨拙的POST。作为替代,我们来 玩玩GitHub的Issue特性。

    本篇文档是回应Issue #482而添加的。鉴于该问题已经存在,我们就以它为例。先获取它。

    >>> r = requests.get('https://api.github.com/repos/kennethreitz/requests/issues/482')

    >>> r.status_code

    200

    >>> issue = json.loads(r.text)

    >>> print issue[u'title']

    Feature any http verb in docs

    >>> print issue[u'comments']

    3

    Cool,有3个评论。我们来看一下最后一个评论。

    >>> r = requests.get(r.url + u'/comments')

    >>> r.status_code

    200

    >>> comments = r.json()

    >>> print comments[0].keys()

    [u'body', u'url', u'created_at', u'updated_at', u'user', u'id']

    >>> print comments[2][u'body']

    Probably in the "advanced" section

    嗯,那看起来似乎是个愚蠢之处。我们发表个评论来告诉这个评论者他自己的愚蠢。那么,这个评论者是谁呢?

    >>> print comments[2][u'user'][u'login']

    kennethreitz

    好,我们来告诉这个叫肯尼思的家伙,这个例子应该放在快速上手指南中。根据GitHub API文档, 其方法是POST到该话题。我们来试试看。

    >>> body = json.dumps({u"body": u"Sounds great! I'll get right on it!"})

    >>> url = u"https://api.github.com/repos/kennethreitz/requests/issues/482/comments"

    >>> r = requests.post(url=url, data=body)

    >>> r.status_code

    404

    额,这有点古怪哈。可能我们需要验证身份。那就有点纠结了,对吧?不对。Requests简化了多种身份验证形式的使用, 包括非常常见的Basic Auth。

    >>> from requests.auth import HTTPBasicAuth

    >>> auth = HTTPBasicAuth('fake@example.com', 'not_a_real_password')

    >>> r = requests.post(url=url, data=body, auth=auth)

    >>> r.status_code

    201

    >>> content = r.json()

    >>> print content[u'body']

    Sounds great! I'll get right on it.

    精彩!噢,不!我原本是想说等我一会,因为我得去喂一下我的猫。如果我能够编辑这条评论那就好了! 幸运的是,GitHub允许我们使用另一个HTTP动词,PATCH,来编辑评论。我们来试试。

    >>> print content[u"id"]

    5804413

    >>> body = json.dumps({u"body": u"Sounds great! I'll get right on it once I feed my cat."})

    >>> url = u"https://api.github.com/repos/kennethreitz/requests/issues/comments/5804413"

    >>> r = requests.patch(url=url, data=body, auth=auth)

    >>> r.status_code

    200

    非常好。现在,我们来折磨一下这个叫肯尼思的家伙,我决定要让他急得团团转,也不告诉他是我在捣蛋。 这意味着我想删除这条评论。GitHub允许我们使用完全名副其实的DELETE方法来删除评论。我们来清除该评论。

    >>> r = requests.delete(url=url, auth=auth)

    >>> r.status_code

    204

    >>> r.headers['status']

    '204 No Content'

    很好。不见了。最后一件我想知道的事情是我已经使用了多少限额(ratelimit)。查查看,GitHub在响应头部发送这个信息, 因此不必下载整个网页,我将使用一个HEAD请求来获取响应头。

    >>> r = requests.head(url=url, auth=auth)

    >>> print r.headers

    ...

    'x-ratelimit-remaining': '4995'

    'x-ratelimit-limit': '5000'

    ...

    很好。是时候写个Python程序以各种刺激的方式滥用GitHub的API,还可以使用4995次呢。

    响应头链接字段

    许多HTTP API都有响应头链接字段的特性,它们使得API能够更好地自我描述和自我显露。

    GitHub在API中为 分页 使用这些特性,例如:

    >>> url = 'https://api.github.com/users/kennethreitz/repos?page=1&per_page=10'

    >>> r = requests.head(url=url)

    >>> r.headers['link']

    '<https://api.github.com/users/kennethreitz/repos?page=2&per_page=10>;; rel="next", <https://api.github.com/users/kennethreitz/repos?page=6&per_page=10>;; rel="last"'

    Requests会自动解析这些响应头链接字段,并使得它们非常易于使用:

    >>> r.links["next"]

    {'url': 'https://api.github.com/users/kennethreitz/repos?page=2&per_page=10', 'rel': 'next'}

    >>> r.links["last"]

    {'url': 'https://api.github.com/users/kennethreitz/repos?page=7&per_page=10', 'rel': 'last'}

  • 相关阅读:
    Django学习路10_创建一个新的数据库,指定列名并修改表名
    设计模式_单例模式的懒汉式实例化
    设计模式_理解单例设计模式
    Django学习路9_流程复习
    Django学习路8_学生表和班级表级联并相互查询信息
    Django学习路7_注册app到能够在页面上显示app网页内容
    es6基础:类、继承、重写
    简单的下拉刷新
    callback&&callback()
    转 五大浏览器四大内核
  • 原文地址:https://www.cnblogs.com/xxsl/p/6116439.html
Copyright © 2020-2023  润新知