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

posted @ 2018-01-02 15:54  Downtime  阅读(417)  评论(0编辑  收藏  举报
TOP