POST请求是一种特殊类型的HTTP方法,当我们向网络上的服务发送数据时使用。我们在使用表单的网站上使用它们–当我们登录时,当我们发送消息或发布图片时。应用程序也使用POST请求与其他服务互动,发送数据,JSON是一种常见的数据交换格式。
Requests
库是Python中最受欢迎的HTTP客户端库之一。它目前在Github上有超过45000颗星,在PyPI上的下载量为每月115M!与通过无头浏览器发送数据相比,它使发送POST请求的程序化过程简单得多。在无头浏览器中,我们需要编写脚本来导航到一个网站,在各个字段之间移动,在最后提交数据之前用所需的数据填充每个字段。通过发送POST请求,我们直接跳到最后的提交步骤。请求也是一个比浏览器小得多的库,因此有更好的性能和内存使用。
在这篇文章中,我们将介绍如何使用Requests构造一个POST请求,以及它如何使我们的过程更加简单。
用Requests建立一个JSON POST请求
- 将请求方式设置为POST
- 设置POST数据
- 设置POST头信息
- POST JSON数据
作为一个例子,让我们从建立一个JSON POST请求开始,这是一个艰难的过程。别担心,Requests稍后将为我们简化这个过程我们使用httpbin.org服务,它返回一个JSON响应,详细说明发送的内容。
1.将请求方式设置为POST
Requests有一个非常简单的基于HTTP动词的设计,这意味着为了得到一个响应,我们调用它的.post()方法,提供我们的URI作为一个参数。它还为GET、PUT和PATCH请求提供类似的方法。
2.设置POST数据
为了实际发送一些数据,我们提供一个数据参数。默认情况下,数据是以HTML表单的形式发送的,就像我们在网上提交任何表单一样。请求将内容类型设置为 “application/x-www-form-urlencoded”,因此没有必要设置任何头文件。
检查httpbin.org服务的响应,我们可以看到 “form “键下作为表单数据发送的内容。
>>> r.text '{\n "args": {}, \n "data": "", \n "files": {}, \n "form": {\n "key": "value"\n }, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Content-Length": "9", \n "Content-Type": "application/x-www-form-urlencoded", \n "Host": "httpbin.org", \n "User-Agent": "python-requests/2.25.1", \n "X-Amzn-Trace-Id": "Root=1-60df1a04-0384d3ce7d9ac00b5855064b"\n }, \n "json": null, \n "origin": "**.***.**.***", \n "url": "https://httpbin.org/post"\n}\n'
如果我们想发送JSON,我们可以提供一个JSON格式的字符串。在我们的例子中,我们使用json模块将一个字典转换成JSON格式的字符串,准备发送:
3.设置POST头信息
我们的JSON例子不可能像现在这样工作。对于许多服务,我们可能会得到一个400(坏请求)的HTTP状态代码。为了防止这种情况,我们还需要通知我们正在调用的服务,我们的数据是JSON,所以它可以被正确处理。为了做到这一点,我们在请求头中把 “内容类型 “设置为 “application/json”。
4.POST JSON数据
如果你认为我们到目前为止的JSON例子看起来有点复杂–你是完全正确的。请求使得将所有这些减少到一个更简单的调用变得非常容易。我们只需提供一个 “json “参数和我们的数据。Requests将正确设置我们的头信息,并自动为我们编码JSON格式的字符串。
读取JSON响应
通过检查我们服务的响应,我们可以看到返回的数据也是一个JSON格式的字符串。这只是文本,所以我们需要自己解析它,以便在我们的Python脚本中使用它。
>>> r.text '{\n "args": {}, \n "data": "{\\"key\\": \\"value\\"}", \n "files": {}, \n "form": {}, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Content-Length": "16", \n "Content-Type": "application/json", \n "Host": "httpbin.org", \n "User-Agent": "python-requests/2.25.1", \n "X-Amzn-Trace-Id": "Root=1-60df0aaa-3105fc35436042571335fa22"\n }, \n "json": {\n "key": "value"\n }, \n "origin": "**.***.**.***", \n "url": "https://httpbin.org/post"\n}\n'
另外,如果我们想以JSON对象的形式访问响应,我们也可以通过对响应对象调用.json()来使用Request内置的JSON解码器。
>>> r.json() {'args': {}, 'data': '{"key": "value"}', 'files': {}, 'form': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '16', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.25.1', 'X-Amzn-Trace-Id': 'Root=1-60deee08-4e9c76b6457826d5001b76fa'}, 'json': {'key': 'value'}, 'origin': '**.***.**.***', 'url': 'http://httpbin.org/post'}
在会话中发出POST请求
作为最后一个例子,让我们使用Request登录Hacker News,并提交一些表单数据,结合request.Session()对象登录。我们收到的任何cookie都将存储在该对象中,并将在以后对会话的.get()调用中重复使用。
对于我们的例子,我们将搜索新闻页面的响应文本,以确认我们是否显示了注销链接,表明我们被提供了一个登录的页面。
[文中代码源自Scrapingbee]
总 结
你已经看到Requests使我们向网站或服务发布数据变得如此简单,以及我们如何通过使用它来减少我们应用程序中的许多普通代码。这种简单的设计肯定有助于它在Python社区的成功,使它成为开发者的最爱。在你使用一个完整的无头浏览器来发送你的数据之前,你绝对应该考虑使用 Requests。