Pythonでクエリ文字列をurlencodeする方法は?


552

送信する前に、この文字列をURLエンコードしようとしています。

queryString = 'eventName=' + evt.fields["eventName"] + '&' + 'eventDescription=' + evt.fields["eventDescription"]; 

回答:


561

次のように、パラメーターをurlencode()マッピング(dict)または2タプルのシーケンスとして渡す必要があります。

>>> import urllib
>>> f = { 'eventName' : 'myEvent', 'eventDescription' : 'cool event'}
>>> urllib.urlencode(f)
'eventName=myEvent&eventDescription=cool+event'

Python 3以上

使用する:

>>> urllib.parse.urlencode(f)
eventName=myEvent&eventDescription=cool+event

これは、一般的に使用される意味でのURLエンコードを行わないことに注意してください(出力を見てください)。そのためにurllib.parse.quote_plus


12
「urllib.urlencodeが常にうまくいくとは限らないことに注意してください。問題は、一部のサービスが引数の順序を考慮しているため、辞書を作成すると失われることに注意してください。 」
Blairg23 2015

16
技術的には、これはサービスのバグですよね。
holdenweb 2015

5
完全なクエリ引数文字列を作成せずに、文字列のURLを安全にしたい場合はどうすればよいでしょうか。
Mike 'Pomax' Kamermans '

1
@ Mike'Pomax'Kamermans-たとえば、stackoverflow.com / questions / 12082314 /…を参照するか、この質問に対するRickyの回答。
bgporter 2016年

1
@ bk0あなたの方法は辞書に対してのみ有効で、文字列に対しては有効ではないようです。
JDガンボア2018

1021

Python 2

あなたが探しているのはurllib.quote_plus

>>> urllib.quote_plus('string_of_characters_like_these:$#@=?%^Q^$')
'string_of_characters_like_these%3A%24%23%40%3D%3F%25%5EQ%5E%24'

Python 3

Python 3では、urllibパッケージは小さなコンポーネントに分割されています。使用しますurllib.parse.quote_plusparse子モジュールに注意してください)

import urllib.parse
urllib.parse.quote_plus(...)

4
ありがとう!私の場合しかし私は置く必要があります:import urllib.parse ... urllib.parse.quote_plus(query)
ivkremer

3
非常に良いですが、なぜUnicodeに使用されないのですか?URL文字列がUnicodeの場合、それをUTF-8にエンコードする必要があります。それを行う他の方法はありますか?
Karl Doenitz、2015

7
これはうまく機能しますが、このパラメーターを追加するまで、一部のオンラインサービス(REST)にアクセスできませんでしたsafe = '; /?:@&= + $、'
rovyko

私は、Python 3でそれを試みたが、することができませんでした:stackoverflow.com/questions/40557606/...
amphibient

1
python3 -c "import urllib.parse, sys; print(urllib.parse.quote_plus(sys.argv[1])) "string to encode"コマンドラインのワンライナー
Amos Joshua

52

urllibの代わりにリクエストをお試しください。urlencodeに煩わされる必要はありません。

import requests
requests.get('http://youraddress.com', params=evt.fields)

編集:

順序付けされた名前と値のペアまたは名前の複数の値が必要な場合は、paramsを次のように設定します。

params=[('name1','value11'), ('name1','value12'), ('name2','value21'), ...]

辞書を使用する代わりに。


5
これは、名前と値のペアの順序の問題に対処していません。また、これには、プロジェクトで実行できない可能性のある外部ライブラリをインストールする権限が必要です。
dreftymac 2013

OPで機能する最小限のコードを投稿しました。OPは注文されたペアを要求しませんでしたが、それも実行可能です。私の更新を参照してください。
Barney

@dreftymac:これは順序付けに対処します(質問の一部ではありませんでした)、私の最新の回答を読んでください。
Barney

36

環境

  • Python(バージョン2.7.2)

問題

  • URLエンコードされたクエリ文字列を生成したい。
  • 名前と値のペアを含む辞書またはオブジェクトがあります。
  • 名前と値のペアの出力順序を制御できるようにする必要があります。

解決

  • urllib.urlencode
  • urllib.quote_plus

落とし穴

以下は、いくつかの落とし穴に対処する方法を含む完全なソリューションです。

### ********************
## init python (version 2.7.2 )
import urllib

### ********************
## first setup a dictionary of name-value pairs
dict_name_value_pairs = {
  "bravo"   : "True != False",
  "alpha"   : "http://www.example.com",
  "charlie" : "hello world",
  "delta"   : "1234567 !@#$%^&*",
  "echo"    : "user@example.com",
  }

### ********************
## setup an exact ordering for the name-value pairs
ary_ordered_names = []
ary_ordered_names.append('alpha')
ary_ordered_names.append('bravo')
ary_ordered_names.append('charlie')
ary_ordered_names.append('delta')
ary_ordered_names.append('echo')

### ********************
## show the output results
if('NO we DO NOT care about the ordering of name-value pairs'):
  queryString  = urllib.urlencode(dict_name_value_pairs)
  print queryString 
  """
  echo=user%40example.com&bravo=True+%21%3D+False&delta=1234567+%21%40%23%24%25%5E%26%2A&charlie=hello+world&alpha=http%3A%2F%2Fwww.example.com
  """

if('YES we DO care about the ordering of name-value pairs'):
  queryString  = "&".join( [ item+'='+urllib.quote_plus(dict_name_value_pairs[item]) for item in ary_ordered_names ] )
  print queryString
  """
  alpha=http%3A%2F%2Fwww.example.com&bravo=True+%21%3D+False&charlie=hello+world&delta=1234567+%21%40%23%24%25%5E%26%2A&echo=user%40example.com
  """ 


23

これを試して:

urllib.pathname2url(stringToURLEncode)

urlencode辞書でしか機能しないため、機能しません。quote_plus正しい出力を生成しませんでした。


本当に助かります!私の場合、URLエンコードする文字列の一部しかありません。たとえば、に変換my stringしたいですmy%20string。あなたのソリューションはその魅力のように機能します!
TanguyP 2016

%20代わりに私のために働いた+。ありがとう
Jossef Harush

21

urllib.urlencodeが常にうまくいくとは限らないことに注意してください。問題は、一部のサービスが引数の順序に注意を払っており、辞書の作成時に失われることです。そのような場合には、Rickyが示唆したように、urllib.quote_plusの方が適しています。


2
あなたはタプルのリストを渡した場合には罰金やジャムために動作します:>>> import urllib >>> urllib.urlencode([('name', 'brandon'), ('uid', 1000)]) 'name=brandon&uid=1000'
ブランドンロードス


6

将来の参照用(例:python3用)

>>> import urllib.request as req
>>> query = 'eventName=theEvent&eventDescription=testDesc'
>>> req.pathname2url(query)
>>> 'eventName%3DtheEvent%26eventDescription%3DtestDesc'

1
通常、値をURLエンコードするだけで、ここで行った操作は無効なGETクエリになります
Codewithcheese

'c:/2 < 3'Windowsでの出力は'///C://2%20%3C%203'です。出力するだけのものが欲しい'c:/2%20%3C%203'
binki

3

Python 2と3の両方をサポートする必要があるスクリプト/プログラムで使用するために、6つのモジュールはquote関数とurlencode関数を提供します。

>>> from six.moves.urllib.parse import urlencode, quote
>>> data = {'some': 'query', 'for': 'encoding'}
>>> urlencode(data)
'some=query&for=encoding'
>>> url = '/some/url/with spaces and %;!<>&'
>>> quote(url)
'/some/url/with%20spaces%20and%20%25%3B%21%3C%3E%26'

2

urllib.parse.urlencode()でエラーが発生する場合は、urllib3モジュールを試してください。

構文は次のとおりです。

import urllib3
urllib3.request.urlencode({"user" : "john" }) 

1

まだ言及されていないかもしれないもう1つのことは、そのパラメーターが存在しないのではなくurllib.urlencode()、ディクショナリー内の空の値をストリングとしてエンコードするNoneことです。これが一般的に望ましいかどうかはわかりませんが、私のユースケースに適合しないため、を使用する必要がありますquote_plus


0

Python 3 urllib3が正しく動作するため、公式ドキュメントに従って次のように使用できます

import urllib3

http = urllib3.PoolManager()
response = http.request(
     'GET',
     'https://api.prylabs.net/eth/v1alpha1/beacon/attestations',
     fields={  # here fields are the query params
          'epoch': 1234,
          'pageSize': pageSize 
      } 
 )
response = attestations.data.decode('UTF-8')
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.