requests, 一个超级强大的Python 爬虫库

更多内容在

Python的Requests库是一个简单而强大的HTTP库,用于发送各种HTTP请求。它由Kenneth Reitz创建,旨在使HTTP请求变得简单、直观,同时提供丰富的功能来处理网络请求和响应。

github地址:https://github.com/psf/requests

首先,导入Requests模块:

import requests

现在,尝试获取一个网页。在这个例子中,获取GitHub的公共时间线:

r = requests.get('https://api.github.com/events')

现在,我们有一个名为r的响应对象。我们可以从这个对象中获取我们所需的所有信息。

Requests的简单API意味着所有形式的HTTP请求都同样直观。例如,这是你发起HTTP POST请求的方式:

requests.post('https://httpbin.org/post', data={'key': 'value'})

那么其他HTTP请求类型:PUT、DELETE、HEAD和OPTIONS呢?这些也都同样简单:

requests.put('https://httpbin.org/put')requests.delete('https://httpbin.org/delete')requests.head('https://httpbin.org/get')requests.options('https://httpbin.org/get')

在URL中传递参数 你经常想要在URL的查询字符串中发送一些数据。如果你手工构造URL,这些数据会在URL后面以问号后跟键/值对的形式给出,例如httpbin.org/get?key=val

Requests允许你使用字符串字典的形式提供这些参数,使用params关键字参数。例如,如果你想传递key1=value1key2=value2httpbin.org/get,你会使用以下代码:

requests.get('https://httpbin.org/get', params={'key1': 'value1', 'key2': 'value2'})

你可以看到URL已经被正确编码,通过打印URL:

print(r.url)  # 输出:https://httpbin.org/get?key2=value2&key1=value1

注意,任何值为None的字典键都不会被添加到URL的查询字符串中。

你也可以将列表作为值传递:

requests.get('https://httpbin.org/get', params={'key1': ['value1']})

响应内容 我们可以读取服务器响应的内容。再次考虑GitHub时间线:

r.text  # 输出:[{"repository": {"open_issues": 0, "url": "https://github.com/...}}

Requests会自动解码服务器的内容。大多数Unicode字符集都会被无缝解码。

当你发起请求时,Requests会根据HTTP头猜测响应的编码。你可以通过r.encoding属性找到Requests猜测的编码,并更改它:

r.encoding  # 输出:'utf-8'

如果你更改了编码,Requests将在你调用r.text时使用新的值。你可能希望在任何情况下都这样做,特别是在你可以应用特殊逻辑来确定内容编码的情况下。例如,HTML和XML有能力在它们的主体中指定它们的编码。在这种情况下,你应该使用r.content来找到编码,然后设置r.encoding。这将让你能够使用正确的编码与r.text一起使用。

Requests也会在需要时使用自定义编码。如果你已经创建了自己的编码并注册了codecs模块,你可以直接使用编解码器名称作为r.encoding的值,Requests将为你处理解码。

二进制响应内容 你也可以将响应体作为字节访问,用于非文本请求:

r.content  # 输出:b'[{"repository": {"open_issues": 0, "url": "https://github.com/...}}

如果安装了像brotli或brotlicffi这样的Brotli库,gzipdeflate传输编码将自动为你解码。例如,要从请求返回的二进制数据创建图像,你可以使用以下代码:

from PIL import Image, ImageIOi = Image.open(BytesIO(r.content))

JSON响应内容 还有一个内置的JSON解码器,以防你正在处理JSON数据:

r.json()  # 输出:[{"repository": {"open_issues": 0, "url": "https://github.com/...}}

如果JSON解码失败,r.json()会引发异常。例如,如果响应得到204(无内容),或者响应包含无效的JSON,尝试r.json()会引发requests.exceptions.JSONDecodeError。这个包装异常为可能由不同Python版本和json序列化库抛出的多个异常提供了互操作性。

请注意,调用的成功并不表示响应的成功。一些服务器可能在失败的响应中返回JSON对象(例如,HTTP 500的错误详情)。这样的JSON将被解码并返回。要检查请求是否成功,请使用r.raise_for_status()或检查r.status_code是否是你期望的。

原始响应内容 在极少数情况下,如果你想从服务器获取原始套接字响应,你可以访问r.raw。如果你想这样做,请确保你在初始请求中设置了stream=True。一旦你这样做了,你可以这样做:

r.raw  # 输出:<http.client.HTTPResponse object at 0x101194810> read 10 b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'

然而,通常你应该使用这样的模式来保存正在流式传输的内容:​​​​​​​

with open(filename, 'wb') as fd:    for chunk in iter_content(chunk_size=128):        fd.write(chunk)

使用Response.iter_content将处理许多你在使用Response.raw时本来需要处理的事情。当流式下载时,上述是推荐和首选的方式来检索内容。请注意,chunk_size可以自由调整到可能更适合你用例的数字。

注意 关于使用r.textr.content的一个重要注意事项。r.text会自动解码transfer-encodingsr.content是原始字节流——它不会转换响应内容。如果你真的需要访问返回的字节,使用r.content

自定义头部 如果你想在请求中添加HTTP头部,只需将字典传递给headers参数。例如,我们在之前的例子中没有指定我们的用户代理:

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

注意:自定义头部的优先级低于更具体的信息来源。例如:

  • 使用headers=设置的Authorization头部将被.netrc中指定的凭据覆盖,这又会被子URL中提供的代理凭据覆盖。

  • 如果你被重定向到其他主机,Authorization头部将被移除。

  • Proxy-Authorization头部将被URL中提供的代理凭据覆盖。

  • 当我们能够确定内容长度时,Content-Length头部将被覆盖。

此外,Requests根本不会根据指定的自定义头部改变其行为。头部只是被传递到最终请求中。

注意:所有头部值必须是字符串、字节串或Unicode。虽然允许,但建议避免传递Unicode头部值。

更复杂的POST请求 通常,你想要发送一些表单编码的数据——就像HTML表单一样。要做到这一点,只需传递一个字典到data参数。你的数据字典将在请求时自动进行表单编码:

requests.post('https://httpbin.org/post', data={'key1': 'value1', 'key2': 'value2'})

data参数还可以为每个键有多个值。这可以通过使data既不是列表的元组也不是字典的列表值来完成。这在表单有多个使用相同键的元素时特别有用:

requests.post('https://httpbin.org/post', data=[('key1', 'value1'), ('key1', 'value2')])

或者

requests.post('https://httpbin.org/post', data={'key1': ['value1', 'value2']})

有时,你可能想要发送不是表单编码的数据。如果你传递的是files而不是data,那么数据将直接发布。例如,GitHub API v3接受JSON编码的POST/PATCH数据:​​​​​​​

import jsonrequests.post('https://api.github.com/some/endpoint', data=json.dumps({'some': 'data'})

请注意,上述代码不会添加Content-Type头部(特别是不会将其设置为application/json)。如果你需要设置该头部并且不想自己编码,你也可以直接使用json参数(在版本2.4.2中添加):

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

注意,如果传递了files,则会忽略json参数。

POST一个Multipart编码的文件 Requests使得上传Multipart编码的文件变得简单:

requests.post('https://httpbin.org/post', files={'file': open('report.xls', 'rb')})

你可以明确设置文件名、内容类型和头部:

requests.post('https://httpbin.org/post', files={'file': ('report.xls', open('report.xls', 'rb

Requests库的更多功能参考官方文档:https://requests.readthedocs.io/en/lates

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿玩AI

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值