Python'da bir sorgu dizesini urlencode nasıl?


552

Ben göndermeden önce bu dize urlencode çalışıyorum.

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

Yanıtlar:


561

Parametrelerinizi urlencode()bir eşleme (dikte) veya bir dizi 2 tuple olarak geçirmeniz gerekir, örneğin:

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

Python 3 veya üstü

kullanın:

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

Bu olmadığını Not değil yaygın kullanılan anlamda (çıkışta göz) kodlayan url yapmak. Bu kullanım için urllib.parse.quote_plus.


12
"Urllib.urlencode her zaman hile yapmaz. Sorun, bazı hizmetler sözlüğü oluşturduğunuzda kaybolur argümanların sırasına önem vermektir. Bu gibi durumlarda, urllib.quote_plus daha iyi, Ricky önerdiği gibi. "
Blairg23

16
Teknik olarak, bu hizmetlerde bir hata, değil mi?
holdenweb

5
tam bir sorgu bağımsız değişkeni dizesi oluşturmadan bir dize URL'sini güvenli hale getirmek istiyorsanız bunu nasıl yaparsınız?
Mike 'Pomax' Kamermans

1
@ Mike'Pomax'Kamermans - bkz. Örneğin stackoverflow.com/questions/12082314/… veya Ricky'nin bu soruya cevabı.
bgporter

1
@ bk0, yönteminizin yalnızca sözlükler için geçerli olduğu, dizeler için geçerli olmadığı anlaşılıyor.
JD Gamboa

1021

Python 2

Aradığın şey 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'te, urllibpaket daha küçük bileşenlere ayrılmıştır. Kullanacaksınız urllib.parse.quote_plus( parsealt modülü not edin )

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

4
Teşekkürler! Benim durumumda ancak koymak gerekir:import urllib.parse ... urllib.parse.quote_plus(query)
ivkremer

3
çok iyi, ama neden Unicode için kullanılmıyor? url dizesi Unicode ise, UTF-8 kodlamak gerekir. Bunu yapmak için başka bir yolu var mı?
Karl Doenitz

7
Bu harika çalışıyor, ancak şu parametreyi ekleyene kadar bazı çevrimiçi hizmetlere (REST) ​​erişemedim safe = '; /
?:

Python 3'te denedim ama başaramadım: stackoverflow.com/questions/40557606/…
amphibient

1
python3 -c "import urllib.parse, sys; print(urllib.parse.quote_plus(sys.argv[1])) "string to encode"komut satırında bir astar için
Amos Joshua

52

Urllib yerine istekleri deneyin ve urlencode ile uğraşmanıza gerek yok!

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

DÜZENLE:

Bir ad için sıralı ad-değer çiftlerine veya birden çok değere ihtiyacınız varsa aşağıdaki gibi parametreler ayarlayın:

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

sözlük kullanmak yerine.


5
Bu, ad değeri çiftlerini sipariş etme konusunu ele almaz, ayrıca proje için gerçekleştirilemeyen harici kitaplıkların yüklenmesine izin verilmesini gerektirir.
dreftymac

Ben OP için işe yarayacak en az kod yayınladı. OP sipariş edilen çiftleri talep etmedi, ancak aynı zamanda yapılabilir, güncellememe bakın.
Barney

@ dreftymac: Bu siparişi ele alıyor (sorunun bir parçası olmasa da), lütfen güncellenmiş cevabımı okuyun.
Barney

36

bağlam

  • Python (sürüm 2.7.2)

Sorun

  • Bir urlen kodlanmış sorgu dizesi oluşturmak istiyorsunuz.
  • Ad-değer çiftlerini içeren bir sözlüğünüz veya nesneniz var.
  • Ad-değer çiftlerinin çıktı sırasını kontrol edebilmek istiyorsunuz.

Çözüm

  • urllib.urlencode
  • urllib.quote_plus

tuzaklar

Misal

Aşağıdakiler, bazı tuzaklarla nasıl başa çıkılacağı dahil olmak üzere eksiksiz bir çözümdür.

### ********************
## 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

Bunu dene:

urllib.pathname2url(stringToURLEncode)

urlencodeişe yaramaz çünkü sadece sözlüklerde çalışır. quote_plusdoğru çıktıyı vermedi.


Bu gerçekten faydalı! Benim durumumda, ben sadece örneğin ben dönüştürmek istiyorum URL-encode ve istediğim bir dize bir kısmını sahip my stringüzere my%20string. Çözümünüz bunun için bir cazibe gibi çalışıyor!
TanguyP

Beni almak için çalıştı %20yerine +. Teşekkürler
Jossef Harush

21

Urllib.urlencode'un her zaman hile yapmadığını unutmayın. Sorun, bazı hizmetlerin sözlüğü oluşturduğunuzda kaybolan argümanların sırasını önemsemesidir. Bu gibi durumlarda, Ricky'nin önerdiği gibi urllib.quote_plus daha iyidir.


2
Eğer bir tuples listesini geçirirseniz iyi çalışır ve düzeni korur:>>> import urllib >>> urllib.urlencode([('name', 'brandon'), ('uid', 1000)]) 'name=brandon&uid=1000'
Brandon Rhodes

8

Python 3'te bu benimle çalıştı

import urllib

urllib.parse.quote(query)

6

gelecekteki referanslar için (ör: python3 için)

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

1
genellikle sadece değerleri kodlamak istiyorsanız, burada yaptığınız geçersiz bir GET sorgusu yapar
Codewithcheese

'c:/2 < 3'Windows için çıktı '///C://2%20%3C%203'. Sadece çıktı alabilecek bir şey istiyorum 'c:/2%20%3C%203'.
binki

3

Hem python 2 hem de 3'ü desteklemesi gereken komut dosyalarında / programlarda kullanım için, altı modül alıntı ve urlencode işlevleri sağlar:

>>> 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 () size hata veriyorsa, urllib3 modülünü deneyin.

Sözdizimi aşağıdaki gibidir:

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

1

Daha önce bahsedilmemiş olabilecek başka bir şey, söz konusu parametrenin bulunmaması yerine urllib.urlencode()sözlükteki boş değerleri dize olarak kodlayacağıdır None. Bunun tipik olarak istenip istenmediğini bilmiyorum, ancak kullanım durumuma uymuyor, bu yüzden kullanmam gerekiyor quote_plus.


0

Python 3 için urllib3 düzgün çalışıyor, resmi belgelerine göre aşağıdaki gibi kullanabilirsiniz :

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')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.