在Python中的POST请求中传递"+"字符

Dou*_*tle 7 python python-requests

我试图在Python脚本中进行一些自动化,但我遇到了一个问题.我正在尝试对服务器进行POST.

url = 'http://www.example.com'
params = {'arg0': 'value', 'arg1': '+value'}

f = urllib.urlopen(url, urllib.urlencode(params))
print f.read()
Run Code Online (Sandbox Code Playgroud)

我已经完成了对相同浏览器操作的wireshark捕获,其中第二个arg arg1被传递+value,但是当我使用Python时,它+被更改为%2B,即

Line-based text data: application/x-www-form-urlencoded
arg0=value&arg1=%2Bvalue
Run Code Online (Sandbox Code Playgroud)

应该是什么时候:

Line-based text data: application/x-www-form-urlencoded
arg0=value&arg1=+value
Run Code Online (Sandbox Code Playgroud)

我也使用了Requests模块,似乎做了同样的事情.

url = 'http://www.example.com'
params = {'arg0': 'value', 'arg1': '+value'}

f = requests.post(url, params)
Run Code Online (Sandbox Code Playgroud)

当你遇到与'+'相关的问题时谷歌不是你的朋友,因为它似乎是其他许多问题.

Mar*_*ers 10

+引用GET或POST数据时,该字符是空格的正确编码.因此,文字+字符也需要被转义,以免被解码到另一端的空间.请参阅RFC 2396,第2.2节,第3.4节HTML规范,application/x-www-form-urlencoded部分:

控制名称和值将被转义.空格字符由"+"替换,然后保留字符按[RFC1738]第2.2节中的描述进行转义.

如果要将数据发布到不将+字符解码为空格的应用程序,而是将此类数据视为文字加符号,则需要使用该urllib.quote函数+自行编码参数,指定不对字符进行编码:

import urllib
def urlencode_withoutplus(query):
    if hasattr(query, 'items'):
        query = query.items()
    l = []
    for k, v in query:
        k = urllib.quote(str(k), safe=' /+')
        v = urllib.quote(str(v), safe=' /+')
        l.append(k + '=' + v)
    return '&'.join(l)
Run Code Online (Sandbox Code Playgroud)

演示:

>>> urlencode_withoutplus({'arg0': 'value', 'arg1': '+value'})
'arg0=value&arg1=+value'
Run Code Online (Sandbox Code Playgroud)

使用时requests,您只需将上述函数的结果作为data值传入,但在这种情况下,您需要手动设置内容类型:

requests.post(url, urlencode_withoutplus(query),
    headers={'Content-Type': 'application/x-www-form-urlencoded'})
Run Code Online (Sandbox Code Playgroud)


And*_*den 5

urllib2.quote(' ')     # '%20'
urllib2.unquote('%20') # ' '
Run Code Online (Sandbox Code Playgroud)

那么为什么不直接取消引用参数部分:

f = urllib.urlopen(url, urllib.unquote(urllib.urlencode(params)))
Run Code Online (Sandbox Code Playgroud)