2012-05-26 16 views
6

URLを作成して、urllibモジュールを使用してリクエストを送信できるようにしようとしています。今、あなたはあなたがオブザーバー二つのことをすることができますfinal_urlの形式で私のquery_stringを比較する場合urlencode pythonを使用してクエリ文字列を作成する

>>> initial_url = "http://www.stackoverflow.com" 
>>> search = "Generate+value" 
>>> params = {"data":initial_url,"search":search} 
>>> query_string = urllib.urlencode(params) 
>>> query_string 
'search=Generate%2Bvalue&data=http%3A%2F%2Fwww.stackoverflow.com' 

は、私は、以下の方法を試してみましたこれを達成するために今の私のfinal_url

url = "www.example.com/find.php?data=http%3A%2F%2Fwww.stackoverflow.com&search=Generate+value" 

する必要がありますと仮定してみましょう

1)パラメータの順序は、data=()&search=ではなく逆になります。012

2)も、私は最初の変更は、辞書のランダムな振る舞いが原因であると考えてい

Generate+value+をコードしていました。ですから、私はOrderedDict to reverse the dictionaryを使っています。 、私はpython 2.6.5を使用していますように私は

pip install ordereddict 

をした。しかし、私はそう

>>> od = OrderedDict((('a', 'first'), ('b', 'second'))) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'OrderedDict' is not defined 

をしようとすると、私のコードでそれを使用することはできませんよ、私の質問はでOrderedDictを使用する正しい方法は何ですpython 2.6.5とurlencodeはをGenerate+valueに無視するようにするにはどうすればいいですか?

また、URLを作成する正しい方法ですか。

答えて

15

+のエンコードについて心配する必要はありません。これは、URLをエスケープした後でサーバーに復元する必要があります。名前付きパラメータの順序は関係ありません。 OrderedDictを考慮

、それはPythonの中に組み込まれていないあなたはcollectionsからそれをインポートする必要があります。あなたのpythonが古すぎると、モジュールcollectionsでの使用をOrderedDictを持っていない場合

from urllib import urlencode, quote 
# from urllib.parse import urlencode # python3 
from collections import OrderedDict 

initial_url = "http://www.stackoverflow.com" 
search = "Generate+value" 
query_string = urlencode(OrderedDict(data=initial_url,search=search)) 

encoded = "&".join("%s=%s" % (key, quote(parameters[key], safe="+")) 
    for key in ordered(parameters.keys())) 

とにかく、パラメータの順序は問題ではありません。

safeパラメータがquoteであることに注意してください。 +がエスケープされないようにしますが、サーバーはGenerate+valueGenerate valueと解釈します。 +を手動でエスケープするには、%2Bと書いて%を安全な文字としてマークすることができます。

+0

私は 'コレクションからインポートOrderedDict'を試みましたが、今は' ImportError:OrderedDictという名前をインポートできません。私はPython '2.6.5' – RanRag

+0

を使用しています。これはpyton 2.4から入手可能です。 'import collections'を実行すると、何が得られますか? –

+0

コレクションを正常にインポートできますが、エラーはスローされません。私は 'OrderedDict'がPython 2.7から導入されました。 – RanRag

3

最初に、httpリクエストのパラメータの順序は完全に無関係にする必要があります。そうでなければ、側の解析ライブラリは何か間違っています。

第2に、もちろん+がコード化されています。 +は、エンコードされたURLのスペースのプレースホルダとして使用されるため、yor生の文字列に+が含まれている場合は、これをエスケープする必要があります。urlencodeは、エンコードされていない文字列を期待しています。すでにエンコードされている文字列を渡すことはできません。質問と他の回答に

+0

ありがとうございます。私は間違いを尋ねる前にチェックしなかった。 – RanRag

0

いくつかのコメントは:

  1. あなたはurllib.urlencodeで順序を保持したい場合は、代わりにマッピング(辞書)のK/Vのペアの順序付けられたシーケンスを提出します。あなたがdictを渡すとき、urlencodeは反復可能なシーケンスをつかむためにちょうどfoo.items()を呼び出します。

# urllib.urlencode accepts a mapping or sequence # the output of this can vary, because `items()` is called on the dict urllib.urlencode({"data": initial_url,"search": search}) # the output of this will not vary urllib.urlencode((("data", initial_url), ("search", search)))

あなたはまた、どのように処理されるか反復可能な値に調整するsecondard doseq引数に渡すことができます。

  1. パラメータの順序は関係ありません。例えば、これらの2つのURLを取る:

    https://example.com?foo=bar&bar=foo https://example.com?bar=foo&foo=bar

    httpサーバは無関係な、これらのパラメータではなく、希望のURLを比較するために設計された機能の順序を考慮する必要があります。安全にURLを比較するには、これらのパラメータをソートする必要があります。 URIの仕様は、重複キーをサポートしていますが、優先度や順序に対応していない

    https://example.com?foo=3&foo=2&foo=1

ただし、重複キーを検討してください。所与のアプリケーションにおいて

、これらはそれぞれ異なる結果を引き起こす可能性と同様に有効である:

https://example.com?foo=1&foo=2&foo=3 
https://example.com?foo=1&foo=3&foo=2 
https://example.com?foo=2&foo=3&foo=1 
https://example.com?foo=2&foo=1&foo=3 
https://example.com?foo=3&foo=1&foo=2 
https://example.com?foo=3&foo=2&foo=1 
  1. +での一部のため%20対URLエンコード形式の空間を(表し予約文字でありますパス)。 urllib.urlencodeurllib.quote_plus()urllib.quote()ではなく)を使用してエスケープします。最も可能性が高いだけでこれをやってみたかったOP:生成

initial_url = "http://www.stackoverflow.com" search = "Generate value" urllib.urlencode((("data", initial_url), ("search", search)))

:出力として

data=http%3A%2F%2Fwww.stackoverflow.com&search=Generate+value

関連する問題