【问题标题】:Using urllib2 to make a post request with headers使用 urllib2 发出带有标头的 post 请求
【发布时间】:2014-07-22 08:18:04
【问题描述】:

我想向具有特定数据和标头类型的 URL 发送发布请求。使用这两个链接我发现了如何做到这一点,但它不起作用:
https://stackoverflow.com/questions/5693931/python-post-request
How do I send a custom header with urllib2 in a HTTP Request?
这是我的代码:

import urllib
import urllib2

url = 'https://clients6.google.com/rpc'
values = [
    {"method": "pos.plusones.get",
     "id": "p",
     "params": {
                "nolog": True,
                "id": "http://www.newswhip.com",
                "source": "widget",
                "userId": "@viewer",
                "groupId": "@self"
                },
     "jsonrpc": "2.0",
     "key": "p",
     "apiVersion": "v1"
    }]
headers = {"Content-type" : "application/json:"}

data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()
print the_page

我可以在 Postman Rest Client 中使用这些值获得结果。但执行此代码后,结果是:

Traceback (most recent call last):
  File "D:/Developer Center/Republishan/republishan2/republishan2/test2.py", line 22, in <module>
    data = urllib.urlencode(values)
  File "C:\Python27\lib\urllib.py", line 1312, in urlencode
    raise TypeError
TypeError: not a valid non-string sequence or mapping object

我也尝试过使用字典而不是这样的列表:

values = {"method": "pos.plusones.get",
     "id": "p",
     "params": {
                "nolog": True,
                "id": "http://www.newswhip.com",
                "source": "widget",
                "userId": "@viewer",
                "groupId": "@self"
                },
     "jsonrpc": "2.0",
     "key": "p",
     "apiVersion": "v1"
    }

它执行脚本但结果包含错误:

{"error":{"code":-32700,"message":"Unable to parse json","data":[{"domain":"global","reason":"parseError","message":"Unable to parse json"}]}}

正如我所说,我可以使用 Postman Rest Client 使用列表而不是字典来执行脚本。 在 Postman 中查看结果: 我该怎么办?

【问题讨论】:

  • values 应该是字典而不是列表。试试values = {"method": "pos.plusones.get", ...., "apiVersion": "v1"}
  • 问题已更新,它工作但结果是一个错误。
  • 一些服务器错误,我想。检查您发送的值的格式是否正确,并且服务器以相同的方式期望它。
  • 这些值正在与 Rest 客户端一起使用!我认为需要在 urllib 中进行额外配置。
  • @sk11 看我问题中的图片

标签: python http-post urllib2


【解决方案1】:

看起来 urllib.urlencode 不理解嵌套的字典:

     In [38]: urllib.urlencode({"a": "asas", "df": {"sds": 123, "t": "fgfg"}})
     Out[38]: 'a=asas&df=%7B%27t%27%3A+%27fgfg%27%2C+%27sds%27%3A+123%7D'

或者你的例子:

     In [41]: urllib.urlencode(values)
     Out[41]: 'jsonrpc=2.0&apiVersion=v1&id=p&params=%7B%27nolog%27%3A+True%2C+%27source%27%3A+%27widget%27%2C+%27userId%27%3A+%27%40viewer%27%2C+%27id%27%3A+%27http%3A%2F%2Fwww.newswhip.com%27%2C+%27groupId%27%3A+%27%40self%27%7D&key=p&method=pos.plusones.get'

看,“params”中的大括号搞砸了。

我不确定如何使用 urllib 来解决这个问题。所以我会推荐请求库。 http://docs.python-requests.org/en/latest/user/quickstart/#custom-headers

简而言之,它看起来像这样(您需要先安装 requests 库,例如使用 pip:pip install requests):

     import requests
     import json

     url = 'https://clients6.google.com/rpc'
     values = {
         "method": "pos.plusones.get",
         "id": "p",
         "params": {
                    "nolog": True,
                    "id": "http://www.newswhip.com",
                    "source": "widget",
                    "userId": "@viewer",
                    "groupId": "@self"
                   },
          "jsonrpc": "2.0",
          "key": "p",
          "apiVersion": "v1"
     }
     headers = {"content-type" : "application/json"}

     req = requests.post(url, data=json.dumps(values), headers=headers)
     print req.text

它对我有用。

【讨论】:

  • 正是这个 sn-p 对我产生了影响“data=json.dumps(values)”,因为我什至没有 dict JSON,而是一个简单的对象,但它没有使用请求正确发送。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
  • 2021-08-13
  • 2013-01-24
  • 1970-01-01
  • 2013-08-03
相关资源
最近更新 更多