requests
Python 的内置 urllib 模块,可以用于访问资源,但是,用起来比较麻烦。
requests 是一个第三方库,在处理 URL 资源上面非常方便,这也是入门爬虫比较推荐的库之一。
安装 requests
如果安装了 Anaconda 这一步可以省略,否则,可以使用下面的命令来安装 requests:
$ pip install requests
上手 requests
发送请求
使用 requests,需要先导入 requests 模块:
>>> import requests
使用 get()
获取某个页面。以 requests 官方文档提及的 Github 公共时间线为例:
>>> url = "https://api.github.com/events"
>>> resp = requests.get(url)
在这里,requests 的 get() 方法返回一个 Response
对象,赋值给变量 resp
。现在可以通过这个对象获取需要的内容。
响应内容
>>> resp.status_code # 响应码,200 表示正常访问
200
>>> resp.text
'[{"id":"11696703469","type":"CreateEvent","actor":{"id":59443325,"login":"mahmoudjafarinejad",...'
>>> resp.encoding
'utf-8'
status_code
返回的是响应码,200
在这里表示正常访问。resp.text
在这里返回的是响应的内容。在返回的响应内容,requests 会自动推测文本编码,可以使用 encoding
属性来查看具体使用了什么编码,例如文中使用该属性返回 utf-8
。
二进制响应内容
返回的 Response
对象,可以使用 content
属性获得字节对象:
>>> resp.content
b'[{"id":"11696703469","type":"CreateEvent","actor":{"id":59443325,"login":"mahmoudjafarinejad",...'
JSON 响应内容
requests 可以处理 JSON 数据。但这中间也有些需要注意的地方,先看代码:
>>> resp.json()
[{'id': '11697045499', 'type': 'IssueCommentEvent', 'actor': {'id': 5268763, 'login': 'zz-jason', ...]
在这里使用 json()
可以获得 JSON 内容。这里需要注意:如果解码失败,该方法会抛出异常。例如,若返回的响应码是 401
,尝试访问 resp.json()
时,就会抛出 ValueError: No JSON object could be decoded
异常。
还有一个需要注意的地方,并不是说成功调用 resp.json()
就表示响应成功。有些服务器在失败的响应中包含一个 JSON 对象。这个时候调用 resp.json()
返回的将是这个包含错误细节的 JSON 对象。所以要检测是否响应成功还需要配合使用 resp.status_code
。
传递 URL 参数
当访问网页的时候,我们可能会遇到带参数的 URL,当使用 requests 的时候,我们可以传入 dict 作为参数传入(这里以 http://httpbin.org
为例):
>>> resp = requests.get('http://httpbin.org/get', params={'key1': 'value1', 'key2': 'value2'})
>>> resp.url
'http://httpbin.org/get?key1=value1&key2=value2'
在上面的例子当中,传入 key1=value1
和 key2=value2
到指定的 URL 中。使用 resp.url
可以看到 URL 已被正确编码。
传递 dict 作为参数的时候,dict 中值为 None 的键都不会被添加到 URL 的查询字符串中。
定义请求头
有时候直接使用 get() 方法访问网站时,返回的响应码并不是 200。这是因为有些网站有反爬机制,这个时候可以定义请求头,模拟浏览器正常访问网站,这里我们以豆瓣为例,在没有定义请求头的情况下尝试使用 get() 方法:
>>> url ="https://www.douban.com/"
>>> resp = requests.get(url)
>>> resp.status_code
418
可以看到这里返回的响应码是 418
。现在定义请求头,再次访问:
>>> headers = {'User-Agent': 'Mozilla/5.0'}
>>> resp = requests.get(url, headers=headers)
>>> resp.status_code
200
这个时候,返回的响应码为 200,表示访问成功。那么这个时候就可以利用返回的 Response 对象获取需要的内容。
这里提醒下: 就上面以豆瓣为例,不要频繁发起请求,若是频繁请求,有可能会被认为是恶意攻击,而且这样也会对服务器造成负担。
POST 请求
当需要发送一些编码为表单形式的数据。这个时候,可以使用 post()
方法,并传递一个字典给 data
参数。requests 在发出请求的时候会将传入的数据字典编码为表单形式:
>>> data = {'key1': 'value1', 'key2': 'value2'}
>>> resp = requests.post('http://httpbin.org/post', data=data)
>>> print(resp.text)
{
...
"form": {
"key1": "value1",
"key2": "value2"
},
...
}
timeout 参数
可以告诉 requests 在经过 timeout
参数所给定的时间停止响应。(timeout 参数以秒为单位)
>>> resp = requests.get(url, timeout=2)
这里表示在 2 秒后超时。
以上关于 requests 简单上手的内容,更多详细的内容可以访问下面的链接进行详细参阅:
参考资料
来源
- “Requests: HTTP for Humans™”.requests.readthedocs.io.Retrieved 5 March 2020.
- 廖雪峰.“Python 教程”.liaoxuefeng.com.[2020-03-05].