10

Python スクリプトでいくつかの自動化を行おうとしていますが、問題が発生しました。サーバーに POST を実行しようとしています。

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

f = urllib.urlopen(url, urllib.urlencode(params))
print f.read()

arg12 番目の引数が として渡される同等のブラウザ操作の Wireshark キャプチャを+value実行しましたが、Python でそれを行うと、+に変更されます%2B

Line-based text data: application/x-www-form-urlencoded
arg0=value&arg1=%2Bvalue

それがいつあるべきか:

Line-based text data: application/x-www-form-urlencoded
arg0=value&arg1=+value

Requests モジュールも使用しましたが、同じことをしているようです。

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

f = requests.post(url, params)

'+' に関連する問題が発生した場合、Google はあなたの味方ではありません。

4

2 に答える 2

11

この+文字は、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)

デモ:

>>> urlencode_withoutplus({'arg0': 'value', 'arg1': '+value'})
'arg0=value&arg1=+value'

を使用する場合requests、上記の関数の結果をdata値として単純に渡すことができますが、その場合はコンテンツ タイプを手動で設定する必要があります。

requests.post(url, urlencode_withoutplus(query),
    headers={'Content-Type': 'application/x-www-form-urlencoded'})
于 2012-09-21T09:45:15.210 に答える
5
urllib2.quote(' ')     # '%20'
urllib2.unquote('%20') # ' '

では、パラメータ部分の引用符を外してみませんか。

f = urllib.urlopen(url, urllib.unquote(urllib.urlencode(params)))
于 2012-09-21T09:54:14.333 に答える