2010-04-03 35 views
30

Sto provando a urlencode un dizionario in python con urllib.urlencode. Il problema è che devo codificare una matrice.urlencode una matrice di valori

Il risultato deve essere:

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

Ma il risultato che ottiene è:

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

Ho provato diverse cose, ma io non riesco a ottenere il risultato giusto.

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

Se uso cgi.parse_qs di decodificare una stringa di query corretta, ottengo questo come risultato:

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

Ma se ho codificare quel risultato, ottengo un risultato sbagliato indietro. C'è un modo per produrre il risultato atteso?

+0

'cig.parse_qs' è deprecato (solo mantenuto per compatibilità con le versioni precedenti), quindi potrebbe essere meglio usare' urlparse.parse_qs' – ChristopheD

+0

Grazie per il suggerimento. L'ho usato solo per il confronto, quindi non è realmente usato. – Ikke

risposta

53

La soluzione è molto più semplice di quelle elencate sopra.

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

Nota il vero. Vedi http://docs.python.org/library/urllib.html#urllib.urlencode la variabile doseq.

Come nota a margine, non è necessario [] affinché funzioni come un array (motivo per cui urllib non lo include). Ciò significa che non è necessario aggiungere [] a tutti i tasti dell'array.

+0

Se non si aggiunge [], php utilizzerà solo criteri = problema e ignorerà il "membro" –

+0

Vedere anche la risposta per questa domanda: http://stackoverflow.com/questions/6243051/how-to -pass-an-array-within-a-query-string –

+1

Per chiarire, Python non si preoccupa se ci sono '' [] ': lo convertirà correttamente indipendentemente. Ma sì, il PHP (e forse altri linguaggi?) Si preoccupa, quindi se si ha una dipendenza esterna da tali sistemi, è meglio lasciare il comando '[]' 's ... sembra davvero strano in Python. – CSTobey

10

È possibile utilizzare un elenco di coppie chiave-valore (tuple):

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

Peccato che questo sia l'unico modo. ma ha risolto il problema. – Ikke

+0

Bene, è molto facile scrivere una funzione che trasforma il dict con le liste in una lista di tuple. –

+0

solo una nota per gli altri, per generare la stringa urlencoded direttamente da un normale dict, tutto ciò che devi fare è 'urllib.urlencode (d.items())' – dlrust

2

Listcomp di valori:

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

Astrarre questo fuori a lavorare per qualsiasi dizionario dei parametri e convertirlo in una lista di tuple:

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) 

che ora dovrebbe funzionare sia per l'esempio precedente, nonché un dizionario con alcune stringhe di alcuni matrici come valori:

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