为什么我不能使用urlencode来编码json格式数据?

时间:2011-11-28 08:20:37

标签: python json urlencode python-2.7

我在python 2.7中遇到了关于urlencode的问题:

>>> import urllib
>>> import json
>>> urllib.urlencode(json.dumps({'title':"hello world!",'anonymous':False,'needautocategory':True}))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/urllib.py", line 1280, in urlencode
    raise TypeError
TypeError: not a valid non-string sequence or mapping object

5 个答案:

答案 0 :(得分:16)

urlencode可以编码dict,但不能编码字符串。 json.dumps的输出是一个字符串。

根据您想要的输出,不要在JSON中编码dict:

>>> urllib.urlencode({'title':"hello world!",'anonymous':False,'needautocategory':True})
'needautocategory=True&anonymous=False&title=hello+world%EF%BC%81'

或将整个事物包裹在一个词典中:

>>> urllib.urlencode({'data': json.dumps({'title':"hello world!",'anonymous':False,'needautocategory':True})})
'data=%7B%22needautocategory%22%3A+true%2C+%22anonymous%22%3A+false%2C+%22title%22%3A+%22hello+world%5Cuff01%22%7D'

或改为使用quote_plus()urlencode使用quote_plus作为键和值):

>>> urllib.quote_plus(json.dumps({'title':"hello world!",'anonymous':False,'needautocategory':True}))
'%7B%22needautocategory%22%3A+true%2C+%22anonymous%22%3A+false%2C+%22title%22%3A+%22hello+world%5Cuff01%22%7D'

答案 1 :(得分:12)

因为urllib.urlencode "converts a mapping object or a sequence of two-element tuples to a “percent-encoded” string..."。你的字符串不是这些。

我认为您需要urllib.quoteurllib.quote_plus

答案 2 :(得分:2)

json.dumps()返回一个字符串。

urllib.urlencode()期望以映射对象或元组的格式进行查询。请注意,它不期望一个字符串。

您将第一个作为第二个参数传递,导致错误。

答案 3 :(得分:2)

导入库

import request
import json

spec是一个字典对象

spec = {...}

将字典对象转换为json

data = json.dumps(spec, ensure_ascii=False)

并最终使用json格式的参数规范

进行请求
response = requests.get(
    'http://localhost:8080/...',
    params={'spec': data}
)

分析回复......

答案 4 :(得分:0)

对于那些会出错的人:

  

AttributeError:模块'urllib'没有属性'urlencode'

这是因为urllib已在Python 3中拆分


这是Python 3的代码:

import urllib.parse
dict = {
    "title": "Hello world",
    "anonymous": False,
    "needautocategory": True
}
urllib.parse.urlencode(dict)  # 'title=Hello+world&anonymous=False&needautocategory=True'