zoukankan      html  css  js  c++  java
  • Requests:Python HTTP Module学习笔记(一)(转)

    Requests:Python HTTP Module学习笔记(一)

    在学习用python写爬虫的时候用到了Requests这个Http网络库,这个库简单好用并且功能强大,完全可以代替python的标准库urllib2。在学习的同时把我的学习笔记记录下来,资料基本上都是从Requests官网翻译过来的,欢迎指出有错误或者有表述的不准确的地方。

    1.介绍
    Requests: HTTP for Humans
    一句话:为地球人准备的网络库

    python的标准库urllib2已经提供了大部分你所需要的HTTP功能了,为什么还需要Requests库来提供相同的功能呢?因为urllib2的API比较零散,它们编写的时间和网络环境都不一样,利用它(urllib2)完成简单的任务需要做大量的工作。

    2.安装
    安装也很简单,用easy_install命令: 
    easy_install requests

    用pip命令:
    pip install requests

    源代码在这里github

    3.例子
    使用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:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import urllib2
    
    gh_url = 'https://api.github.com'
    req = urllib2.Request(gh_url)
    
    password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
    password_manager.add_password(None, gh_url, 'user', 'pass')
    
    auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)
    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'
    

    爬虫的入门可以参考42区的一个小爬虫 

    4.功能介绍

    Requests支持所有的Http请求类型,例如:

    >>> r = requests.post("http://httpbin.org/post")
    >>> 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")
    

    在URL中传递参数(Passing Parameters In URLs)

    想在请求URL中带参数,例如这样httpbin.org/get?key=val,Requests允许你提供一个字典作为这些参数:

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

    你可以看到输出的URL已经经过正确的编码:

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

    响应内容(Response Content)

    请求发送后,我们可以读取服务器返回的内容,看刚刚的例子:

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

    Requests会自动decode服务器返回的内容,大部分unicode的字符都可以顺利的decode。

    当访问r.text时,Requests会根据response的Http标头信息使用相应的文本编码输出信息,可以查看Requests使用的是什么类型的编码并改变它:

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

    如果改变了编码类型,当调用r.text的时候,Requests会使用你设置的编码类型输出信息。

    二进制的相应内容(Binary Response Content)

    对于非文本的请求,也可以把返回的响应内容作为字节类型输出:

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

    gzip和deflate编码会为你自动解码,
    例如想把一个请求返回的二进制数据装换成图像,可以这样写:

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

    以json格式返回响应内容(JSON Response Content)

    Requests还提供了一个json的decoder,可以方便的处理json格式的数据

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

    调用r.json()方法时,如果请求的内容不是json格式,会导致json解码失败,抛出异常。

    原始的响应内容(Raw Response Content)

    如过想从服务器返回的响应中获取原始的套接字响应,可以调用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'
    

    自定义头文件(Custom Headers)

    如果想在请求时添加一个Http标头,可以在请求时添加一个字典类型的参数,例如:

    >>> 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请求(More complicated POST requests)

    通常,如果想要发送一些表单类型的数据(像Html表单这样的数据),在这里,只需要把Html的表单数据构造成一个字典类型的参数附带在请求中即可。

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

    很多时候我们发送的数据并不是表单类型的数据,就像我们想传递一个字符串类型而不是字典类型的数据时,数据会被直接的发送出去:

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

    上传Multipart-Encoded的文件(POST a Multipart-Encoded File)

    Requests提供简单的方式去发送Multipart-Encoded文件:

    >>> 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"
       },
       ...
    }
    

    响应的状态代码(Response Status Codes)

    我们可以查看响应的状态码

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

    为了方便参考,Requests还配备了一个内置的状态码对象

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

    如果我们的请求是一个失败的请求(非200的status code),我们可以调用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
    

    但是,如果我们的Response的status_code是200,当我们调用raise_for_status()时:

    >>> r.raise_for_status()
    None
    

    返回的就是None,All is well.

    响应报头(Response Headers)

    我们可以以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'
    }
    

    我们知道dictionary的key值是大小写敏感的,但这里的dictionary有点特殊,它只是用来保存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

    如果一个response包含Cookies信息,你可以很快速的访问它们:

    >>> url = 'http://httpbin.org/cookies/set/requests-is/awesome'
    >>> r = requests.get(url)
    
    >>> r.cookies['requests-is']
    'awesome'
    

    你可以设置自己的cookies利用cookies这个参数发送到服务器:

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

    重定向和历史(Redirection and History)

    当使用GET和OPTIONS请求类型时,Requests会帮你自动重定向。
    GitHub会重定向所有HTTP请求到HTTPS,我们可以调用response的history方法跟踪重定向:

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

    调用response.history返回的列表包含了一系列为了完成请求而创建的对象,这个列表按照从最开始的请求到最后的请求进行排序。
    如果使用GET和OPTION请求类型,可以设置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]>]
    

    超时(Timeouts)

    你可以设置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的设置只是影响请求的连接过程,不影响下载的response body。

    错误和异常(Errors and Exceptions)

    • 在发生网络问题时(如DNS失败、拒绝连接,等等)Requests会抛出一个ConnectionError的异常。

    • 接收到Http无效的响应时,Requests会抛出一个HTTPError的异常。

    • 如果请求超时了,会抛出一个请求超时的异常。

    • 如果一个请求超过了配置的重定向次数,会抛出TooManyRedirects异常。

    • 所有Requests的异常都显示的继承自requests.exceptions.RequestException.

    对Requests库的入门介绍先到这样,在下一篇日志,我会继续介绍它的一些高级特性。

    (完)

  • 相关阅读:
    odoo service error 更改端口号
    unique 唯一约束
    odoo 注册失败
    odoo 某个字段权限设置
    linux 定时任务
    odoo webside theme
    js 杂记
    vue3入门总结
    vue输出空格
    css等比例缩放图片
  • 原文地址:https://www.cnblogs.com/paisen/p/3399357.html
Copyright © 2011-2022 走看看