如何使用 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 16:49:03  来源:igfitidea点击:

How to make a post request with the Python requests library?

pythonjsondjangopython-3.xcassandra

提问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 dataarguments encodes that dictionary to application/x-www-form-urlencodedform, 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 filtersis a Pythondata structure here, and that it is passed to the jsonkeyword 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-Typeheader to application/json(as you did in your Postman configuration by picking the JSONoption in the dropdown menu after picking rawfor the body).
  • 将 Python 数据结构编码为 JSON(生成与原始 Postman 正文值完全相同的 JSON 值)。
  • Content-Type标题设置为application/json(就像在 Postman 配置中一样,在JSON选择raw正文后在下拉菜单中选择选项)。

requestsis otherwise just an HTTP API, it can't make Cassandra do any more than any other HTTP library. The urllib.request.urlopencode sends GETrequests, and are trivially translated to requestswith:

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 ifbranching and replaced that with using the paramsargument, which translates a dictionary of key-value pairs to a correctly encoded URL query (passing in the user name as the user_namekey).

我删除了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 jsonattribute 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+001and not user&001or user 001?

而且,用户名确实应该是user+001user&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))