如何使用 Python requests 库发出 post 请求?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45201628/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make a post request with the Python requests library?
提问by abautista
I am using the following filters in Postman to make a POST request in a Web API but I am unable to make a simple POST request in Python with the requests library.
我在 Postman 中使用以下过滤器在 Web API 中发出 POST 请求,但我无法使用请求库在 Python 中发出简单的 POST 请求。
First, I am sending a POST request to this URL (http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets) with the following filters in Postman applied to the Body, with the raw and JSON(application/json) options selected.
首先,我向此 URL ( http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets)发送 POST 请求,将 Postman 中的以下过滤器应用于正文,原始和 JSON(application/json) 选项被选中。
Filters in Postman
{
"filter": {
"filters": [
{
"field": "RCA_Assigned_Date",
"operator": "gte",
"value": "2017-05-31 00:00:00"
},
{
"field": "RCA_Assigned_Date",
"operator": "lte",
"value": "2017-06-04 00:00:00"
},
{
"field": "T_Subcategory",
"operator": "neq",
"value": "Temporary Degradation"
},
{
"field": "Issue_Status",
"operator": "neq",
"value": "Queued"
}],
"logic": "and"
}
}
The database where the data is stored is Cassandra and according to the following links Cassandra not equal operator, Cassandra OR operator, Cassandra Between order by operators, Cassandra does not support the NOT EQUAL TO, OR, BETWEENoperators, so there is no way I can filter the URL with these operators except with AND.
存储数据的数据库是Cassandra,根据下面的链接Cassandra not equal operator, Cassandra OR operator, Cassandra between order by operators, Cassandra 不支持NOT EQUAL TO, OR, BETWEEN运算符,所以我没办法可以使用这些运算符过滤 URL,但使用AND除外。
Second, I am using the following code to apply a simple filter with the requests library.
其次,我使用以下代码对请求库应用一个简单的过滤器。
import requests
payload = {'field':'T_Subcategory','operator':'neq','value':'Temporary Degradation'}
url = requests.post("http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets",data=payload)
But what I've got is the complete data of tickets instead of only those that are not temporary degradation.
但我得到的是门票的完整数据,而不仅仅是那些不是暂时降级的。
Third, the system is actually working but we are experiencing a delay of 2-3 mins to see the data. The logic goes as follows: We have 8 users and we want to see all the tickets per user that are not temporary degradation, then we do:
第三,系统实际上正在工作,但我们看到数据有 2-3 分钟的延迟。逻辑如下:我们有 8 个用户,我们希望查看每个用户的所有非临时降级的票证,然后我们执行以下操作:
def get_json():
if user_name == "user 001":
with urllib.request.urlopen(
"http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets?user_name=user&001",timeout=15) as url:
complete_data = json.loads(url.read().decode())
elif user_name == "user 002":
with urllib.request.urlopen(
"http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets?user_name=user&002",timeout=15) as url:
complete_data = json.loads(url.read().decode())
return complete_data
def get_tickets_not_temp_degradation(start_date,end_date,complete_):
return Counter([k['user_name'] for k in complete_data if start_date < dateutil.parser.parse(k.get('DateTime')) < end_date and k['T_subcategory'] != 'Temporary Degradation'])
Basically, we get the whole set of tickets from the current and last year, then we let Python to filter the complete set by user and so far there are only 10 users which means that this process is repeated 10 times and makes me no surprise to discover why we get the delay...
基本上,我们得到了今年和去年的全套票,然后我们让 Python 按用户过滤了完整的票,到目前为止只有 10 个用户,这意味着这个过程重复了 10 次,这让我毫不意外发现为什么我们会延迟...
My questions is how can I fix this problem of the requests library? I am using the following link Requests library documentationas a tutorial to make it working but it just seems that my payload is not being read.
我的问题是如何解决请求库的这个问题?我使用以下链接请求库文档作为教程来使其工作,但似乎我的有效负载没有被读取。
采纳答案by Martijn Pieters
Your Postman request is a JSON body. Just reproduce that same body in Python. Your Python code is not sending JSON, nor is it sending the same data as your Postman sample.
您的 Postman 请求是一个 JSON 正文。只需在 Python 中重现相同的主体即可。您的 Python 代码不会发送 JSON,也不会发送与 Postman 示例相同的数据。
For starters, sending a dictionary via the data
arguments encodes that dictionary to application/x-www-form-urlencoded
form, not JSON. Secondly, you appear to be sending a single filter.
对于初学者来说,通过data
参数发送字典会将该字典编码为application/x-www-form-urlencoded
表格,而不是 JSON。其次,您似乎发送了一个过滤器。
The following code replicates your Postman post exactly:
以下代码完全复制了您的 Postman 帖子:
import requests
filters = {"filter": {
"filters": [{
"field": "RCA_Assigned_Date",
"operator": "gte",
"value": "2017-05-31 00:00:00"
}, {
"field": "RCA_Assigned_Date",
"operator": "lte",
"value": "2017-06-04 00:00:00"
}, {
"field": "T_Subcategory",
"operator": "neq",
"value": "Temporary Degradation"
}, {
"field": "Issue_Status",
"operator": "neq",
"value": "Queued"
}],
"logic": "and"
}}
url = "http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets"
response = requests.post(url, json=filters)
Note that filters
is a Pythondata structure here, and that it is passed to the json
keyword argument. Using the latter does two things:
请注意,这里filters
是一个Python数据结构,它被传递给json
关键字参数。使用后者有两件事:
- Encode the Python data structure to JSON (producing the exact same JSON value as your raw Postman body value).
- Set the
Content-Type
header toapplication/json
(as you did in your Postman configuration by picking theJSON
option in the dropdown menu after pickingraw
for the body).
- 将 Python 数据结构编码为 JSON(生成与原始 Postman 正文值完全相同的 JSON 值)。
- 将
Content-Type
标题设置为application/json
(就像在 Postman 配置中一样,在JSON
选择raw
正文后在下拉菜单中选择选项)。
requests
is otherwise just an HTTP API, it can't make Cassandra do any more than any other HTTP library. The urllib.request.urlopen
code sends GET
requests, and are trivially translated to requests
with:
requests
否则只是一个 HTTP API,它不能让 Cassandra 比任何其他 HTTP 库做的更多。该urllib.request.urlopen
代码发送GET
请求,并平凡转换为requests
具有:
def get_json():
url = "http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets"
response = requests.get(url, params={'user_name': user}, timeout=15)
return response.json()
I removed the if
branching and replaced that with using the params
argument, which translates a dictionary of key-value pairs to a correctly encoded URL query (passing in the user name as the user_name
key).
我删除了if
分支并将其替换为使用params
参数,它将键值对字典转换为正确编码的 URL 查询(将用户名作为user_name
键传递)。
Note the json()
call on the response; this takes care of decoding JSON data coming back from the server. This still takes long, you are not filtering the Cassandra data much here.
注意json()
响应中的调用;这负责解码从服务器返回的 JSON 数据。这仍然需要很长时间,您在这里没有对 Cassandra 数据进行太多过滤。
回答by teewuane
I would recommend using the json
attribute instead of data. It handles the dumping for you.
我建议使用json
属性而不是数据。它为您处理倾销。
import requests
data = {'user_name':'user&001'}
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
url = "http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets/"
r = requests.post(url, headers=headers, json=data)
Update, answer for question 3. Is there a reason you are using urllib? I'd use python requests as well for this request.
更新,回答问题 3。您使用 urllib 有什么原因吗?对于这个请求,我也会使用 python 请求。
import requests
def get_json():
r = requests.get("http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets”, params={"user_name": user_name.replace(" ", "&")})
return r.json
# not sure what you're doing here, more context/code example would help
def get_tickets_not_temp_degradation(start_date, end_date, complete_):
return Counter([k['user_name'] for k in complete_data if start_date < dateutil.parser.parse(k.get('DateTime')) < end_date and k['T_subcategory'] != 'Temporary Degradation'])
Also, is the username really supposed to be user+001
and not user&001
or user 001
?
而且,用户名确实应该是user+001
不user&001
还是user 001
?
回答by juanblo
I think, you can use requests library as follows:
我认为,您可以按如下方式使用请求库:
import requests
import json
payload = {'field':'T_Subcategory','operator':'neq','value':'Temporary Degradation'}
url = requests.post("http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets",data=json.dumps(payload))
回答by anuj249
You are sending user in url, use it through post, but its depend upon how end points are implemented. You can try the below code :
您在 url 中发送用户,通过 post 使用它,但它取决于端点的实现方式。您可以尝试以下代码:
import requests
from json import dumps
data = {'user_name':'user&001'}
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
url = "http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets/"
r = requests.post(url, headers=headers, data=dumps(data))