【问题标题】:How to send POST request?如何发送 POST 请求?
【发布时间】:2012-07-04 13:33:21
【问题描述】:

我在网上找到了这个脚本:

import httplib, urllib
params = urllib.urlencode({'number': 12524, 'type': 'issue', 'action': 'show'})
headers = {"Content-type": "application/x-www-form-urlencoded",
            "Accept": "text/plain"}
conn = httplib.HTTPConnection("bugs.python.org")
conn.request("POST", "", params, headers)
response = conn.getresponse()
print response.status, response.reason
302 Found
data = response.read()
data
'Redirecting to <a href="http://bugs.python.org/issue12524">http://bugs.python.org/issue12524</a>'
conn.close()

但我不明白如何在 PHP 中使用它,或者 params 变量中的所有内容是什么,或者如何使用它。我可以帮我解决这个问题吗?

【问题讨论】:

  • 发布请求只是发布请求,不管服务器端是什么。
  • 这会发送一个 POST 请求。然后服务器以 302(重定向)标头响应您的 POST。究竟出了什么问题?
  • 这个脚本看起来不像 python3.2 兼容
  • python3 等价于这个例子可能是:pastebin.com/Rx4yfknM
  • 我建议安装firefox的live http header插件,然后在firefox中打开你的url,然后在live http header插件中查看url的request/response,这样你就会明白params and headers在你的代码。

标签: urllib python-2.x httplib


【解决方案1】:

如果您真的想使用 Python 处理 HTTP,我强烈推荐 Requests: HTTP for Humans。适合您的问题的 POST 快速入门是:

>>> import requests
>>> r = requests.post("http://bugs.python.org", data={'number': 12524, 'type': 'issue', 'action': 'show'})
>>> print(r.status_code, r.reason)
200 OK
>>> print(r.text[:300] + '...')

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>
Issue 12524: change httplib docs POST example - Python tracker

</title>
<link rel="shortcut i...
>>> 

【讨论】:

  • 我无法得到与您在上面所做的相同的结果。我在页面上写了另一个问题编号,然后运行脚本,但我在结果中看不到问题编号。
  • 请将data={'number': 12524, 改为读取data={'number': '12524',.我会自己更改它,但编辑需要超过 6 个字符。谢谢
  • 如何获取json结果?
  • 如果您需要发送 JSON 对象,您应该这样做:json={'number': 12524... 而不是 data=...
  • 为什么答案是“如果你真的想用 Python 处理 HTTP”?处理 HTTP 请求是个坏主意吗?如果是这样,为什么?谁能解释一下?
【解决方案2】:

这是一个没有任何外部 pip 依赖的解决方案,但仅适用于 Python 3+(Python 2 不适用):

from urllib.parse import urlencode
from urllib.request import Request, urlopen

url = 'https://httpbin.org/post' # Set destination URL here
post_fields = {'foo': 'bar'}     # Set POST fields here

request = Request(url, urlencode(post_fields).encode())
json = urlopen(request).read().decode()
print(json)

示例输出:

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "foo": "bar"
  }, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Content-Length": "7", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "Python-urllib/3.3"
  }, 
  "json": null, 
  "origin": "127.0.0.1", 
  "url": "https://httpbin.org/post"
}

【讨论】:

    【解决方案3】:

    您无法使用urllib 实现 POST 请求(仅适用于 GET),而是尝试使用 requests 模块,例如:

    示例 1.0:

    import requests
    
    base_url="www.server.com"
    final_url="/{0}/friendly/{1}/url".format(base_url,any_value_here)
    
    payload = {'number': 2, 'value': 1}
    response = requests.post(final_url, data=payload)
    
    print(response.text) #TEXT/HTML
    print(response.status_code, response.reason) #HTTP
    

    示例 1.2:

    >>> import requests
    
    >>> payload = {'key1': 'value1', 'key2': 'value2'}
    
    >>> r = requests.post("http://httpbin.org/post", data=payload)
    >>> print(r.text)
    {
      ...
      "form": {
        "key2": "value2",
        "key1": "value1"
      },
      ...
    }
    

    示例 1.3:

    >>> import json
    
    >>> url = 'https://api.github.com/some/endpoint'
    >>> payload = {'some': 'data'}
    
    >>> r = requests.post(url, data=json.dumps(payload))
    

    【讨论】:

    • 谢谢。 data=json.dumps(payload) 是我用例的关键
    【解决方案4】:

    通过点击 REST API 端点,使用 requests 库进行 GET、POST、PUT 或 DELETE。在url 中传递rest api 端点url,在data 中传递payload(dict),在headers 中传递标头/元数据

    import requests, json
    
    url = "bugs.python.org"
    
    payload = {"number": 12524, 
               "type": "issue", 
               "action": "show"}
    
    header = {"Content-type": "application/x-www-form-urlencoded",
              "Accept": "text/plain"} 
    
    response_decoded_json = requests.post(url, data=payload, headers=header)
    response_json = response_decoded_json.json()
     
    print(response_json)
    

    【讨论】:

    • 此代码存在缩进和标题参数名称问题。
    • headers 参数错误,而且我们这里没有任何 json。我们应该使用json.dumps(pauload)
    • 感谢 @xilopaint 和 ArashHatami 的语法错误。现已更正。
    【解决方案5】:

    您的数据字典包含表单输入字段的名称,您只需保持正确的值即可查找结果。 form view 标头配置浏览器以检索您声明的数据类型。 使用 requests 库很容易发送 POST:

    import requests
    
    url = "https://bugs.python.org"
    data = {'@number': 12524, '@type': 'issue', '@action': 'show'}
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept":"text/plain"}
    response = requests.post(url, data=data, headers=headers)
    
    print(response.text)
    

    更多关于请求对象:https://requests.readthedocs.io/en/master/api/

    【讨论】:

      【解决方案6】:

      如果您不想使用必须安装的模块,例如requests,并且您的用例非常基础,那么您可以使用urllib2

      urllib2.urlopen(url, body)
      

      在此处查看urllib2 的文档:https://docs.python.org/2/library/urllib2.html

      【讨论】:

        【解决方案7】:

        您可以使用请求库来发出发布请求。 如果负载中有 JSON 字符串,则可以使用 json.dumps(payload) ,这是负载的预期形式。

        
            import requests, json
            url = "http://bugs.python.org/test"
            payload={
                "data1":1234,'data2':'test'
            }
            headers = {
                'Content-Type': 'application/json'
            }
            response = requests.post(url, headers=headers, data=json.dumps(payload))
            print(response.text , response.status_code)
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多