zoukankan      html  css  js  c++  java
  • python的Requests库的使用

    Requests模块:

      Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。Requests 的哲学是以 PEP 20 的习语为中心开发的,所以它比 urllib 更加Pythoner。更重要的是它支持 Python3!

    1.安装:
    pip install requests

    2.Requests 简便的API意味着所有HTTP请求类型都支持:

    1  r = requests.put("http://httpbin.org/put")
    2  r = requests.delete("http://httpbin.org/delete")
    3  r = requests.head("http://httpbin.org/get")
    4  r = requests.options("http://httpbin.org/get")

    3.传递URL参数:

    ①:
    >>> payload = {'key1': 'value1', 'key2': 'value2'}
    >>> r = requests.get("http://httpbin.org/get", params=payload)
    >>> print(r.url)
    输出:http://httpbin.org/get?key2=value2&key1=value1 #通过打印输出该 URL,你能看到URL已被正确编码
    
    ②:
    >>> payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
    >>> r = requests.get('http://httpbin.org/get', params=payload)
    >>> print(r.url)
    输出:http://httpbin.org/get?key1=value1&key2=value2&key2=value3


    4.编码:
    你可以找出 Requests 使用了什么编码,并且能够使用 r.encoding 属性来改变它

    resopnse = requests.get("http://www.baidu.com")
    >>> r.encoding
    'ISO-8859-1'
    >>> r.encoding = 'utf-8'


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

    >>> r = requests.get('https://github.com/timeline.json')
    >>> r.json()
    {'message': 'Hello there, wayfaring stranger. If you’re reading this then you probably didn’t see our blog post a couple of years back announcing that this。。。

      注意:如果 JSON 解码失败, r.json() 就会抛出一个异常。例如,响应内容是 401 (Unauthorized),尝试访问 r.json() 将会抛出 ValueError: No JSON object could be decoded 异常。需要注意的是,成功调用 r.json() 并**不**意味着响应的成功。有的服务器会在失败的响应中包含一个 JSON 对象(比如 HTTP 500 的错误细节)。这种 JSON 会被解码返回。要检查请求是否成功,请使用 r.raise_for_status() 或者检查 r.status_code 是否和你的期望相同。


    6.获取http响应码/响应状态:
    >>> r = requests.get('https://github.com/timeline.json')
    >>> r.status_code
    410 #响应码


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

    1  url = 'https://api.github.com/some/endpoint'
    2  headers = {'user-agent': 'my-app/0.0.1'}
    3  r = requests.get(url, headers=headers)


    8.更加复杂的 POST 请求:

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


    你还可以为 data 参数传入一个元组列表。在表单中多个元素使用同一 key 的时候,这种方式尤其有效:

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

    很多时候你想要发送的数据并非编码为表单形式的。如果你传递一个 string 而不是一个 dict,那么数据会被直接发布出去。
    >>> import json

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


    9.获取响应头:
    r = requests.get("http://www.xxx.com")
    >>> 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-encoding']
    >>>r.headers.get('content-encoding') #这种方法不会报错


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

    1  url = 'http://example.com/some/cookie/setting/url'
    2  r = requests.get(url)
    3  r.cookies['example_cookie_name']
    4 输出:'example_cookie_value'


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

    1  url = 'http://httpbin.org/cookies'
    2  cookies = dict(cookies_are='working')
    3  r = requests.get(url, cookies=cookies)
    4  r.text
    5 输出:'{"cookies": {"cookies_are": "working"}}'



    11.超时:
    你可以告诉 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.


    12.错误与异常:

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

    ②如果 HTTP 请求返回了不成功的状态码, Response.raise_for_status() 会抛出一个 HTTPError 异常。

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

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

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

    Requests的Cookies文档
    这里有一篇关于cookie和session详解的文章挺不错的!

    13.Session会话对象:
    在以上的请求中,每次请求其实都相当于发起了一个新的请求。也就是相当于我们每个请求都用了不同的浏览器单独打开的效果。也就是它并不是指的一个会话,即使请求的是同一个网址。比如:
    import requests

    requests.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
    r = requests.get("http://httpbin.org/cookies")
    print(r.text)
        
    结果是:
    {
      "cookies": {}
    }


    很明显,这不在一个会话中,无法获取 cookies,那么在一些站点中,我们需要保持一个持久的会话怎么办呢?就像用一个浏览器逛淘宝一样,在不同的选项卡之间跳转,这样其实就是建立了一个长久会话。

    解决方案如下:
    import requests

    s = requests.Session()
    s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
    r = s.get("http://httpbin.org/cookies")
    print(r.text)


    在这里我们请求了两次,一次是设置 cookies,一次是获得 cookies

    运行结果:
    {
      "cookies": {
        "sessioncookie": "123456789"
      }
    }

    发现可以成功获取到 cookies 了,这就是建立一个会话到作用。体会一下。
    那么既然会话是一个全局的变量,那么我们肯定可以用来全局的配置了。
    import requests

    s = requests.Session()
    s.headers.update({'x-test': 'true'})
    r = s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})
    print r.text

    通过 s.headers.update 方法设置了 headers 的变量。然后我们又在请求中设置了一个 headers,那么会出现什么结果?
    很简单,两个变量都传送过去了。

    运行结果:
    {
      "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Host": "httpbin.org",
        "User-Agent": "python-requests/2.9.1",
        "X-Test": "true",
        "X-Test2": "true"
      }
    }

    如果get方法传的headers 同样也是 x-test 呢?
    r = s.get('http://httpbin.org/headers', headers={'x-test': 'true'})
    1
        
    r = s.get('http://httpbin.org/headers', headers={'x-test': 'true'})

    它会覆盖掉全局的配置
    {
      "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Host": "httpbin.org",
        "User-Agent": "python-requests/2.9.1",
        "X-Test": "true"
      }
    }

    那如果不想要全局配置中的一个变量了呢?很简单,设置为 None 即可
    r = s.get('http://httpbin.org/headers', headers={'x-test': None})


    运行结果:
    {
      "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Host": "httpbin.org",
        "User-Agent": "python-requests/2.9.1"
      }
    }

    Requests的Session文档

    14.代理:

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

    proxies = {
      "https": "http://41.118.132.69:4433"
    }
    r = requests.post("http://httpbin.org/post", proxies=proxies)
    print r.text

    也可以通过环境变量 HTTP_PROXY 和 HTTPS_PROXY 来配置代理
    export HTTP_PROXY="http://10.10.1.10:3128"
    export HTTPS_PROXY="http://10.10.1.10:1080"

    简单实例:

    1 import requests
    2 
    3 html = requests.get("https://www.baidu.comindex.php?tn=monline_3_dg")
    4 print(html.text)   #返回的是Unicode型的数据。
    5 print(html.content)   #返回的是bytes型也就是二进制的数据。
    6 print(html.status_code)   #返回http状态码
    7 print(html.cookies)   #返回cookie
    8 print(html.headers)   #返回http头信息
    9 print(html.url)   #返回请求的url地址

    附:

    ①Requests的text和content的区别:
      resp.text返回的是Unicode型的数据。
      resp.content返回的是bytes型也就是二进制的数据。

      也就是说,如果你想取文本,可以通过r.text。
      如果想取图片,文件,则可以通过r.content。

    ②编码问题:

      不论使用urllib还是使用requests库经常会遇到中文编码错误的问题,我就经常遇到,因为python安装在windows平台上,cmd的默认编码为GBK,所以在cmd中显示中文时会经常提示gbk编码错误,后来找到了贴在,完美的解决了该问题,下面我分享给大家:

      UnicodeEncodeError: 'gbk' codec can't encode character 'xbb' in position 0: illegal multibyte sequence

    在cmd中我们输出data.read()时,中文乱码,大部分时候是因为print函数,其实print()函数的局限就是Python默认编码的局限,因为系统是win7的,python的默认编码不是'utf-8',改一下python的默认编码成'utf-8'就行了,sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8') #改变标准输出的默认编码
    可以看到该语句修改了python的默认编码为utf8,并赋予了我们的stdout输出,使得python的输出默认编码为utf8,但是当我们在cmd中输出还是中文乱码,这是cmd的锅,cmd不能很好地兼容utf8,而IDLE就可以,甚至在IDLE下运行,连“改变标准输出的默认编码”都不用,因为它默认就是utf8。如果一定要在cmd下运行,那就改一下编码,比如我换成“gb18030”,就能正常显示了:

      import io

      import sys
      sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030') #改变标准输出的默认编码

    data.decode('utf8')完美解决。

    Requets文档

  • 相关阅读:
    【Linux】Apache服务配置
    【Linux】LAMP环境搭建(简易版)
    【Linux】网络应用
    【Linux】系统管理
    【Linux】Linux(一)Linux常用命令
    【php】PDO
    【php】COOKIE和SESSION
    【php】面向对象(五)
    【php】面向对象(四)
    【php】面向对象(三)
  • 原文地址:https://www.cnblogs.com/Downtime/p/8177589.html
Copyright © 2011-2022 走看看