前面写都是基于urllib库来写的,今天开始了解python爬虫常用的工具库,今天介绍第一个库 Requests中文官网

1 安装

1.1 直接安装

要安装 Requests,只要在你的终端中运行这个简单命令即可:

$ pip install requests 

1.2 pycharm安装方法

如果使用的是pycharm,安装方法见下图(顺序为按照箭头的方向操作):

如果安装完成,导入模块验证一下是否成功即可:

>>> import requests
>>>

2 快速上手

2.1 发送请求

使用 Requests 发送网络请求非常简单。 我们从导入 Requests 模块开始:

>>> import requests

获取某个网页:

>>> import requests
>>> r = requests.get('https://www.baidu.com')
>>> print(type(r))
<class 'requests.models.Response'>
>>> print(r.status_code)
200
>>> print(r.encoding)
ISO-8859-1
>>> print(r.cookies)
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>

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

Requests 简便的 API 意味着所有 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")

2.2 传递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)
http://httpbin.org/get?key2=value2&key1=value1

注意字典里值为 None 的键都不会被添加到 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

2.3 响应

读取服务器响应的内容

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

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

>>>r = requests.get('https://api.github.com/events')
>>>r.json()
[{'id': '7018640501', 'type': 'CommitCommentEvent', 'actor': {'id': 758844, 'login': 'glynhudson', 'display_login': 'glynhudson', 'gravatar_id': '', 'url': 'https://api...

读取原始的响应内容: 你想获取来自服务器的原始响应,你可以访问 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)
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'

2.4 定制请求头

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

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

2.5 POST请求

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

>>> playload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post('http://httpbin.org/post', data=playload)
>>> print(r.text)
{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "key1": "value1",
    "key2": "value2"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "close",
    "Content-Length": "23",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.18.4"
  },
  "json": null,
  "origin": "115.171.69.64",
  "url": "http://httpbin.org/post"
}

>>>

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

>>> payload = (('key1', 'value1'), ('key1', 'value2'))
>>> r = requests.post('http://httpbin.org/post', data=payload)
>>> print(r.text)
{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "key1": [
      "value1",
      "value2"
    ]
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "close",
    "Content-Length": "23",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.18.4"
  },
  "json": null,
  "origin": "115.171.69.64",
  "url": "http://httpbin.org/post"
}

>>>

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

>>> import json
>>> import requests
>>> url = 'http://httpbin.org/post'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, data=json.dumps(payload))
>>> print(r.text)
{
  "args": {},
  "data": "{\"some\": \"data\"}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "close",
    "Content-Length": "16",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.18.4"
  },
  "json": {
    "some": "data"
  },
  "origin": "115.171.69.64",
  "url": "http://httpbin.org/post"
}

>>>

此处除了可以自行对 dict 进行编码,你还可以使用 json 参数直接传递,然后它就会被自动编码。这是 2.4.2 版的新加功能:

>>> r = requests.post(url, json=payload)
>>> print(r.text)
{
  "args": {},
  "data": "{\"some\": \"data\"}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "close",
    "Content-Length": "16",
    "Content-Type": "application/json",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.18.4"
  },
  "json": {
    "some": "data"
  },
  "origin": "115.171.69.64",
  "url": "http://httpbin.org/post"
}

>>>

2.6 上传文件

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

2.7 cookie

如果某个响应中包含一些 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"}}'

2.8 超时

你可以告诉 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 秒内没有从基础套接字上接收到任何字节的数据时)

3 高级用法

3.1 会话对象

会话对象让你能够跨请求保持某些参数。它也会在同一个 Session 实例发出的所有请求之间保持 cookie,因为如果没有使用会话对象,每一次请求都相当于新的请求,类似于不同浏览器单独打开请求,如下面的请求:

>>> import requests
>>> requests.get('http://httpbin.org/cookies/set/sessioncookie/123456')
<Response [200]>
>>> r = requests.get('http://httpbin.org/cookies')
>>> print(r.text)
{
  "cookies": {}
}

使用会话对象后,创建对象实例s = requests.Session(),通过s去请求,结果如下:

>>> s = requests.Session()
>>> s.get('http://httpbin.org/cookies/set/sessioncookie/123456')
<Response [200]>
>>> r = s.get('http://httpbin.org/cookies')
>>> print(r.text)
{
  "cookies": {
    "sessioncookie": "123456"
  }
}

>>>

3.2 SSL 证书验证

Requests 可以为 HTTPS 请求验证 SSL 证书,就像 web 浏览器一样。SSL 验证默认是开启的,如果证书验证失败,Requests 会抛出 SSLError:

requests.get('https://www.12306.cn')
requests.exceptions.SSLError: HTTPSConnectionPool(host='www.12306.cn', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))

github设置了,所以返回结果正常

requests.get('https://github.com')
<Response [200]>

3.3 流式上传

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

with open('massive-body') as f:
    requests.post('http://some.url/streamed', data=f)

注意: 建议你用二进制模式(binary mode)打开文件。这是因为 requests 可能会为你提供 header 中的 Content-Length,在这种情况下该值会被设为文件的字节数。如果你用文本模式打开文件,就可能碰到错误。

3.4 代理

如果需要使用代理,你可以通过 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")

具体更多的功能,可以参考文档进一步研究。