RFC 3986的urlencode()

时间:2013-12-27 13:53:17

标签: python python-3.x urlencode

Python有一个非常棒的urlencode()函数,它通过RFC 1738(加号编码)对dict进行编码:

>>> urllib.parse.urlencode({'site':'Stack Overflow','Coder':'Jeff Atwood'})
'Coder=Jeff+Atwood&site=Stack+Overflow'

我找不到使用RFC 3986(百分比编码)的替代品,即使是精细的手册states the following

  

RFC 3986 - 统一资源标识符
  这是现行标准(STD66)。对urllib.parse模块的任何更改都应符合此要求。

这将是预期的输出:

>>> urllib.parse.urlencode({'site':'Stack Overflow','Coder':'Jeff Atwood'})
'Coder=Jeff%20Atwood&site=Stack%20Overflow'

当然我可以自己滚动,但我发现很惊讶我没有找到内置的这样的Python函数。是否有这样的Python函数,我只是没找到?

2 个答案:

答案 0 :(得分:4)

似乎没有内置这样的东西,但是有一个bug请求一个,它甚至附加了一个补丁:http://bugs.python.org/issue13866

答案 1 :(得分:1)

对于字符串,您可以使用:

def percent_encoding(string):
    result = ''
    accepted = [c for c in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~'.encode('utf-8')]
    for char in string.encode('utf-8'):
        result += chr(char) if char in accepted else '%{}'.format(hex(char)[2:]).upper()
    return result

>>> percent_encoding('http://www.google.com')
'http%3A%2F%2Fwww.google.com'

>>> percent_encoding('ñapa')
'%C3%B1apa'

现在,对于字典,您需要对值进行编码,因此您只需要一个将此字典转换为url键/值对的函数,仅对其值进行编码。

def percent_urlencode(dictionary):
    return '&'.join(["{}={}".format(k, percent_encoding(str(v))) for k, v in dictionary.items()])

>>> percent_urlencode({'token': '$%&/', 'username': 'me'})
'username=me&token=%24%25%26%2F'

>>> percent_urlencode({'site':'Stack Overflow','Coder':'Jeff Atwood'})
'site=Stack%20Overflow&Coder=Jeff%20Atwood'