Parámetros de consulta de URL para dictar Python

98

¿Hay alguna forma de analizar una URL (con alguna biblioteca de Python) y devolver un diccionario de Python con las claves y los valores de los parámetros de consulta que forman parte de la URL?

Por ejemplo:

url = "http://www.example.org/default.html?ct=32&op=92&item=98"

rendimiento esperado:

{'ct':32, 'op':92, 'item':98}
Leonardo Andrade
fuente

Respuestas:

188

Usa la urllib.parsebiblioteca :

>>> from urllib import parse
>>> url = "http://www.example.org/default.html?ct=32&op=92&item=98"
>>> parse.urlsplit(url)
SplitResult(scheme='http', netloc='www.example.org', path='/default.html', query='ct=32&op=92&item=98', fragment='')
>>> parse.parse_qs(parse.urlsplit(url).query)
{'item': ['98'], 'op': ['92'], 'ct': ['32']}
>>> dict(parse.parse_qsl(parse.urlsplit(url).query))
{'item': '98', 'op': '92', 'ct': '32'}

Los métodos urllib.parse.parse_qs()y urllib.parse.parse_qsl()analizan las cadenas de consulta, teniendo en cuenta que las claves pueden aparecer más de una vez y que el orden puede ser importante.

Si todavía está en Python 2, urllib.parsese llamó urlparse.

Martijn Pieters
fuente
37

Para Python 3, los valores del dict from parse_qsestán en una lista, porque puede haber varios valores. Si solo quieres el primero:

>>> from urllib.parse import urlsplit, parse_qs
>>>
>>> url = "http://www.example.org/default.html?ct=32&op=92&item=98"
>>> query = urlsplit(url).query
>>> params = parse_qs(query)
>>> params
{'item': ['98'], 'op': ['92'], 'ct': ['32']}
>>> dict(params)
{'item': ['98'], 'op': ['92'], 'ct': ['32']}
>>> {k: v[0] for k, v in params.items()}
{'item': '98', 'op': '92', 'ct': '32'}
reubano
fuente
1
Esto no es exclusivo de Python 3, Python 2 urllib.parse_qstambién devuelve listas para los valores. Menciono esto específicamente en mi respuesta, por cierto, es posible que desee usar urllib.parse_qsl()en su lugar y pegar la lista resultante dict()si solo desea valores únicos.
Martijn Pieters
Parece que la diferencia con parse_qlses que, dado que devuelve una lista de tuplas, convertir eso en un dict mantendrá el último valor en lugar del primero . Esto, por supuesto, supone que había varios valores para empezar.
reubano
11

Si prefiere no utilizar un analizador:

url = "http://www.example.org/default.html?ct=32&op=92&item=98"
url = url.split("?")[1]
dict = {x[0] : x[1] for x in [x.split("=") for x in url[1:].split("&") ]}

Así que no eliminaré lo que está arriba, pero definitivamente no es lo que debería usar.

Creo que leí algunas de las respuestas y parecían un poco complicadas, en caso de que seas como yo, no uses mi solución.

Utilizar este:

from urllib import parse
params = dict(parse.parse_qsl(parse.urlsplit(url).query))

y para Python 2.X

import urlparse as parse
params = dict(parse.parse_qsl(parse.urlsplit(url).query))

Sé que esto es lo mismo que la respuesta aceptada, solo en una línea que se puede copiar.

Tomos Williams
fuente
6
El análisis implica más que simplemente dividir la cadena. También debe manejar la codificación de URL (incluido el +), y urllib.parsetambién genera o ignora los errores según lo solicitado. No estoy seguro de por qué querrías reinventar esta rueda cuando es parte de la biblioteca estándar.
Martijn Pieters
6

Para Python 2.7

In [14]: url = "http://www.example.org/default.html?ct=32&op=92&item=98"

In [15]: from urlparse import urlparse, parse_qsl

In [16]: parse_url = urlparse(url)

In [17]: query_dict = dict(parse_qsl(parse_url.query))

In [18]: query_dict
Out[18]: {'ct': '32', 'item': '98', 'op': '92'}
Anurag Misra
fuente
4

Estoy de acuerdo en no reinventar la rueda, pero a veces (mientras aprendes) ayuda construir una rueda para entender una rueda. :) Entonces, desde una perspectiva puramente académica, ofrezco esto con la advertencia de que el uso de un diccionario supone que los pares de nombre y valor son únicos (que la cadena de consulta no contiene varios registros).

url = 'http:/mypage.html?one=1&two=2&three=3'

page, query = url.split('?')

names_values_dict = dict(pair.split('=') for pair in query.split('&'))

names_values_list = [pair.split('=') for pair in query.split('&')]

Estoy usando la versión 3.6.5 en el IDE inactivo.

Clarius
fuente
0

Porque python2.7estoy usando el urlparsemódulo para analizar la consulta de URL para dictar.

import urlparse

url = "http://www.example.org/default.html?ct=32&op=92&item=98"

print urlparse.parse_qs( urlparse.urlparse(url).query )
# result: {'item': ['98'], 'op': ['92'], 'ct': ['32']} 
Tamim
fuente