如何在Python中使用Urlencode查询字符串?


552

我尝试在提交之前对该字符串进行urlencode。

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

Answers:


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并非总能解决问题。问题在于某些服务关心参数的顺序,当您创建字典时这些参数会丢失。对于这种情况,urllib.quote_plus更好,如Ricky建议的那样。 ”
Blairg23

16
从技术上讲,这是服务中的错误,不是吗?
holdenweb

5
如果只想使字符串URL安全而不构建完整的查询参数字符串,该怎么办?
Mike'Pomax'Kamermans

1
@ Mike'Pomax'Kamermans-参见例如stackoverflow.com/questions/12082314/…或Ricky对这个问题的回答。
bgporter

1
@ bk0,看来您的方法仅对字典有效,而对字符串无效。
JD Gamboa

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_plus(注意parse子模块)

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

4
谢谢!但就我而言,我需要输入:import urllib.parse ... urllib.parse.quote_plus(query)
ivkremer 2014年

3
很好,但是为什么不习惯使用Unicode?如果url字符串是Unicode,我必须将其编码为UTF-8。还有其他方法吗?
Karl Doenitz

7
这很好用,但是直到我添加了此参数safe ='; /?:@&= + $,',我才能访问一些在线服务(REST)
rovyko 2015年

我想,在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"在命令行上使用一个班轮
阿莫斯·约书亚

51

尝试使用请求而不是urllib,您无需费心urlencode!

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

编辑:

如果您需要有序的名称/值对或一个名称的多个值,请按如下所示设置参数:

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

而不是使用字典。


5
这不能解决对名称/值对进行排序的问题,也需要安装可能不适用于该项目的外部库的权限。
dreftymac

我发布了适用于OP的最小代码。OP并未请求有序对,但是它也是可行的,请参阅我的更新。
巴尼(Barney)2013年

@dreftymac:这确实解决了排序问题(尽管这不是问题的一部分),请阅读我的最新答案。
巴尼(Barney)2013年

36

语境

  • Python(版本2.7.2)

问题

  • 您要生成一个urlencoded查询字符串。
  • 您有一个包含名称-值对的字典或对象。
  • 您希望能够控制名称-值对的输出顺序。

  • 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 stringmy%20string。您的解决方案为此具有魅力!
TanguyP '02

为我工作%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 2015年

'c:/2 < 3'在Windows上的输出为'///C://2%20%3C%203'。我想要可以输出的东西'c:/2%20%3C%203'
宾基

3

为了在需要同时支持python 2和python 3的脚本/程序中使用,这六个模块提供了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

可能尚未提到的另一件事是,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')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.