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

16 投票
5 回答
40525 浏览
提问于 2025-04-17 07:12

我在使用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 个回答

3

(1) 导入库

import requests
import json

(2) Spec是一个字典对象

spec = {...}

(3) 将字典对象转换为json格式

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

(4) 最后,用json格式的参数spec发起请求

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

(5) 分析响应结果 ...

23

urlencode 可以把一个字典(dict)转换成特定格式,但不能直接处理字符串。而 json.dumps 的输出结果是一个字符串。

根据你想要的输出结果,你可以选择不把字典转成 JSON:

>>> 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'
17

因为 urllib.urlencode “将一个映射对象或一系列两个元素的元组转换成一个‘百分比编码’的字符串...”。而你的字符串既不是映射对象,也不是两个元素的元组。

我觉得你需要用 urllib.quote 或者 urllib.quote_plus

撰写回答