【python】Request模块

来源:互联网 发布:强矩阵组织 编辑:程序博客网 时间:2024/04/27 23:46

响应状态码

可以检测响应状态码:

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

Requests还附带了一个内置的状态码查询对象:

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

如果发送了一个错误请求(一个 4XX 客户端错误,或者 5XX 服务器错误响应),可以通过 Response.raise_for_status() 来抛出异常:

bad_r = requests.get('http://httpbin.org/status/404')bad_r.status_code>>>400bad_r.raise_for_status()Traceback (most recent call last):  File "requests/models.py", line 832, in raise_for_status    raise http_errorrequests.exceptions.HTTPError: 404 Client Error

当status_code 是 200 ,调用 raise_for_status()

r.raise_for_status()>>>None

响应头

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

r.headers{    'content-encoding': 'gzip',    'transfer-encoding': 'chunked',    'connection': 'close',    'server': 'nginx/1.0.4',    'x-runtime': '148ms',    'etag': '"e1ca502697e5c9317743dc078f67693f"',    'content-type': 'application/json'}

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

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

r.headers['Content-Type']>>>'application/json'r.headers.get('content-type')>>>'application/json'

它还有一个特殊点,那就是服务器可以多次接受同一 header,每次都使用不同的值。但 Requests 会将它们合并,这样它们就可以用一个映射来表示出来

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

url = 'http://httpbin.org/cookies'cookies = dict(cookies_are='working')r = requests.get(url, cookies=cookies)print(r.text)>>>'{"cookies": {"cookies_are": "working"}}'

Cookie 的返回对象为 RequestsCookieJar,它的行为和字典类似,但界面更为完整,适合跨域名跨路径使用。还可以把 Cookie Jar 传到 Requests 中:

jar = requests.cookies.RequestsCookieJar()jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere')url = 'http://httpbin.org/cookies'r = requests.get(url, cookies=jar)print(r.text)>>>'{"cookies": {"tasty_cookie": "yum"}}'

重定向与请求历史

默认情况下,除了 HEAD, Requests 会自动处理所有重定向,可以使用响应对象的 history 方法来追踪重定向

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

例如,Github 将所有的 HTTP 请求重定向到 HTTPS:

r = requests.get('http://github.com')print(r.url)>>>'https://github.com/'print(r.status_code)>>>200print(r.history)>>>[<Response [301]>]

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

r = requests.get('http://github.com', allow_redirects=False)print(r.status_code)>>>301print(r.history)>>>[]

超时

告诉 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 仅对连接过程有效,与响应体的下载无关。 timeout 并不是整个下载响应的时间限制,而是如果服务器在 timeout 秒内没有应答,将会引发一个异常(更精确地说,是在 timeout 秒内没有从基础套接字上接收到任何字节的数据时)If no timeout is specified explicitly, requests do not time out

请求与响应对象

任何时候进行了类似 requests.get() 的调用,你都在做两件主要的事情。其一,你在构建一个 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'}

事件挂钩

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

可用的钩子:

response:
从一个请求产生的响应

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

hooks=dict(response=print_url)

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

def print_url(r, *args, **kwargs):    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 AuthBaseclass 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]>
原创粉丝点击