2010-04-03 37 views
30

Tôi đang cố gắng mã hóa từ điển trong python bằng urllib.urlencode. Vấn đề là, tôi phải mã hóa một mảng.urlencode một mảng giá trị

Kết quả cần phải được:

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

Nhưng kết quả tôi nhận được là:

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

Tôi đã thử một vài điều, nhưng tôi dường như không thể có được kết quả đúng.

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

Nếu tôi sử dụng cgi.parse_qs để giải mã một chuỗi truy vấn chính xác, tôi có được điều này là kết quả:

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

Nhưng nếu tôi mã hóa kết quả đó, tôi nhận được một kết quả sai lại. Có cách nào để tạo ra kết quả mong đợi không?

+0

'cig.parse_qs' không được dùng nữa (chỉ được giữ lại để tương thích ngược), vì vậy, tốt hơn nên sử dụng' urlparse.parse_qs' – ChristopheD

+0

Cảm ơn bạn đã tìm mẹo. Tôi chỉ sử dụng nó để so sánh, vì vậy nó không thực sự được sử dụng. – Ikke

Trả lời

53

Giải pháp này đơn giản hơn nhiều so với các giá trị được liệt kê ở trên.

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

Lưu ý đúng. Xem http://docs.python.org/library/urllib.html#urllib.urlencode biến liều lượng.

Như một lưu ý phụ, bạn không cần [] để nó hoạt động như một mảng (đó là lý do tại sao urllib không bao gồm nó). Điều này có nghĩa là bạn không cần phải thêm [] vào tất cả các phím mảng của bạn.

+0

Nếu bạn không thêm [], php sẽ chỉ sử dụng criterias = issue và sẽ bỏ qua "thành viên" –

+0

Đồng thời xem câu trả lời cho câu hỏi này: http://stackoverflow.com/questions/6243051/how-to -pass-an-array-trong-một-truy vấn-chuỗi –

+1

Để làm rõ, Python không quan tâm nếu '[]' có ở đó: nó sẽ chuyển đổi nó một cách chính xác bất kể. Nhưng có, PHP (và có thể các ngôn ngữ khác?) Không quan tâm, vì vậy nếu bạn có một sự phụ thuộc bên ngoài vào các hệ thống như vậy, tốt nhất là để lại '[]' ... nó trông có vẻ lạ trong Python. – CSTobey

10

Bạn có thể sử dụng một danh sách các cặp khóa-giá trị (các tuple):

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

Quá xấu đây là cách duy nhất. nhưng nó đã giải quyết được vấn đề. – Ikke

+0

Vâng, rất dễ dàng để viết một hàm biến đổi dict với các danh sách thành một danh sách các bộ dữ liệu. –

+0

chỉ là một lưu ý cho những người khác, để tạo ra chuỗi urlencoded thẳng từ một dict thường xuyên, tất cả những gì bạn cần làm là 'urllib.urlencode (d.items())' – dlrust

2

Listcomp các giá trị:

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

Để trừu tượng này ra để làm việc cho bất kỳ từ điển thông số và chuyển đổi nó thành danh sách các bộ dữ liệu:

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) 

Bây giờ nên làm việc cho cả ví dụ trên cũng như từ điển với một số chuỗi nd một số mảng dưới dạng giá trị:

criterias = ['member', 'issue'] 
params = { 
    'criterias[]': criterias, 
} 
url_encode_params(params) 
>>'criterias%5B%5D=member&criterias%5B%5D=issue' 
Các vấn đề liên quan