如何在Python中将字典转换为查询字符串?

162

使用cgi.parse_qs()后,如何将结果(字典)转换回查询字符串?寻找类似于urllib.urlencode()的内容。

使用 urllib.parse.urlencode() 将字典转换为查询字符串。

7
N.B: cgi.parse_qs()已经过时,请使用urlparse.parse_qs()代替。 - johnsyweb
1
参考资料:https://dev59.com/kW035IYBdhLWcg3wH8Ul - dreftymac
4个回答

214

Python 3

urllib.parse.urlencode(query, doseq=False, [...])

映射对象或一个包含str或bytes对象的二元组序列转换为百分号编码的ASCII文本字符串。

—— Python 3 urllib.parse 文档

dict是一种映射对象。

Legacy Python

urllib.urlencode(query[, doseq])
映射对象或一个包含两个元素的元组序列转换为“百分号编码”的字符串... 一系列用'&'字符分隔的key=value对...

—— Python 2.7 urllib 文档


1
这是正确的,但是cgi.parse_qs()返回的dict实际上将list作为其“values”。直接传递这些值将导致查询字符串看起来非常奇怪。 - johnsyweb
足够正确。这会教会我读完整个句子! - johnsyweb
18
urllib.parse.urlencode 是 Python 3 中的一个函数,它用于将字典对象转换为 URL 编码的字符串。URL 编码是一种将特殊字符转换为 ASCII 码的方法,以便于在 URL 中传输。这个函数使用了标准库中的 urllib.parse 模块。 - Denilson Sá Maia
1
问题在于urlencode会将空格转换为+,这是不推荐的。 - user1633272
3
不推荐根据谁的意见? - Ignacio Vazquez-Abrams
显示剩余4条评论

107

在Python 3中,稍有不同:

from urllib.parse import urlencode
urlencode({'pram1': 'foo', 'param2': 'bar'})

输出:'pram1=foo&param2=bar'

为了实现Python2和Python3的兼容性,请尝试以下代码:

try:
    #python2
    from urllib import urlencode
except ImportError:
    #python3
    from urllib.parse import urlencode

12

你需要的是像urllib.urlencode()这样的东西!

但是,当你调用parse_qs()(不同于parse_qsl())时,字典键是唯一的查询变量名,并且值是每个名称的值的列表

为了将此信息传递给urllib.urlencode(),您必须"展平"这些列表。以下是使用元组列表解析的方法:

query_pairs = [(k,v) for k,vlist in d.iteritems() for v in vlist]
urllib.urlencode(query_pairs)

19
或者您可以传递参数doseq=True - Ignacio Vazquez-Abrams
@downvoter:我该如何改进这个答案?我写它已经六年了! - johnsyweb

1
也许你正在寻找类似这样的东西:
def dictToQuery(d):
  query = ''
  for key in d.keys():
    query += str(key) + '=' + str(d[key]) + "&"
  return query

它接受一个字典并将其转换为查询字符串,就像urlencode一样。它将在查询字符串末尾附加最后一个"&",但是如果这是一个问题,return query[:-1]可以解决这个问题。


4
дҪ жҳҜеҗҰйҒҮеҲ°иҝҮstr.join()иҝҷдёӘж–№жі•пјҹд»ҘеҸҠurllib.quote_plus()е‘ўпјҹ - Ignacio Vazquez-Abrams
1
@garbados,你的解决方案在简单情况下应该是有效的。但是,请查看urllib.py中的urlencode(它应该在你的Python安装中),以了解为什么创建查询字符串有时不像你的答案所暗示的那样简单(特别是需要“引用”某些在URL中无效的字符)。@Ignacio还引用了两个函数,可以清理您的实现并使其正确。 - Anthony Cramp
啊,确实。抱歉这个糟糕的实现。这表明我回答那些我从未遇到过的问题时应该更加小心。 - garbados
虽然这可能不是最好的答案,但它正是我在点击此问题标题时想要看到的。我的字典中只有4个项目,我需要将它们转换为由“&”分隔的name=value对。我的值受控制。在我的情况下,str.join()很方便,但我没有使用quote_plus()的必要,因为这不是公共代码 :) 谢谢! - harperville
1
@harperville 但更正确的方式(from urllib.parse import urlencode; urlencode(your_dict))比这个更短更容易!我承认,有时候重新发明轮子,即使质量较差,当访问现有的、设计良好的轮子变得昂贵或不方便时,这是明智的。但在这里,使用现成的轮子比自己制造劣质的轮子更容易和更快。 - Mark Amery

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接