2010-04-03 39 views
30

我想urlencode与urllib.urlencode python中的字典。问题是,我必须编码一个数组。urlencode值的数组

结果必须是:

criterias%5B%5D=member&criterias%5B%5D=issue 
#unquoted: criterias[]=member&criterias[]=issue 

但结果我得到的是:

criterias=%5B%27member%27%2C+%27issue%27%5D 
#unquoted: criterias=['member',+'issue'] 

我已经试过几件事情,但我似乎无法得到正确的结果。

import urllib 
criterias = ['member', 'issue'] 
params = { 
    'criterias[]': criterias, 
} 
print urllib.urlencode(params) 

如果我使用cgi.parse_qs解码正确的查询字符串,我得到这个结果为:

{'criterias[]': ['member', 'issue']} 

但是,如果我编码的结果,我得到一个错误的结果返回。有没有办法产生预期的结果?

+0

'cig.parse_qs'已弃用(仅为保持向后兼容性),所以最好使用'urlparse.parse_qs' – ChristopheD 2010-04-03 11:59:10

+0

感谢您的提示。我只用它来比较,所以没有真正使用它。 – Ikke 2010-04-03 12:03:39

回答

53

该解决方案比上面列出的要简单得多。

>>> import urllib 
>>> params = {'criterias[]': ['member', 'issue']} 
>>> 
>>> print urllib.urlencode(params, True) 
criterias%5B%5D=member&criterias%5B%5D=issue 

注意真。参见http://docs.python.org/library/urllib.html#urllib.urlencode doseq变量。作为一个方面说明,你不需要[]将它作为一个数组来使用(这就是为什么urllib不包括它)。这意味着您不需要将[]添加到所有数组键。

+0

如果不添加[],php只会使用criterias = issue,并且会忽略“成员” – 2015-11-18 15:12:48

+0

另请参阅此问题的答案:http://stackoverflow.com/questions/6243051/how-to -pass-an-array-within-a-query-string – 2015-11-18 15:24:04

+1

为了澄清,Python不关心'[]'是否存在:无论如何,它都会正确转换它。但是,是的,PHP(也许还有其他语言?)确实在意,所以如果你对这样的系统有外部依赖性,最好留下'[]'......它在Python中看起来很奇怪。 – CSTobey 2015-12-16 15:46:55

10

您可以使用键 - 值对(元组)的列表:

>>> urllib.urlencode([('criterias[]', 'member'), ('criterias[]', 'issue')]) 
'criterias%5B%5D=member&criterias%5B%5D=issue' 
+0

太糟糕了,这是唯一的方法。但它解决了这个问题。 – Ikke 2010-04-03 13:32:53

+0

好吧,编写一个函数可以很容易地将带有列表的字典转换为元组列表。 – 2010-04-03 15:30:01

+0

只是其他人的注释,为了从常规字典中直接生成urlencoded字符串,所有你需要做的就是'urllib.urlencode(d.items())' – dlrust 2011-05-04 00:32:34

2

Listcomp值:

>>> criterias = ['member', 'issue'] 
>>> urllib.urlencode([('criterias[]', i) for i in criterias]) 
'criterias%5B%5D=member&criterias%5B%5D=issue' 
>>> 
2

抽象这一点对于任何参数字典工作,并把它转换成元组列表:

import urllib 

def url_encode_params(params={}): 
    if not isinstance(params, dict): 
     raise Exception("You must pass in a dictionary!") 
    params_list = [] 
    for k,v in params.items(): 
     if isinstance(v, list): params_list.extend([(k, x) for x in v]) 
     else: params_list.append((k, v)) 
    return urllib.urlencode(params_list) 

现在,它应该既适用于上述示例,也适用于带有一些字符串的字典a nd一些数组作为值:

criterias = ['member', 'issue'] 
params = { 
    'criterias[]': criterias, 
} 
url_encode_params(params) 
>>'criterias%5B%5D=member&criterias%5B%5D=issue'