Parâmetros de consulta de URL para dict python

98

Existe uma maneira de analisar um URL (com alguma biblioteca Python) e retornar um dicionário Python com as chaves e valores de uma parte dos parâmetros de consulta do URL?

Por exemplo:

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

retorno esperado:

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

Respostas:

187

Use a 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'}

Os métodos urllib.parse.parse_qs()e urllib.parse.parse_qsl()analisam strings de consulta, levando em consideração que as chaves podem ocorrer mais de uma vez e que a ordem pode ser importante.

Se você ainda estiver no Python 2, urllib.parsefoi chamado urlparse.

Martijn Pieters
fonte
37

Para Python 3, os valores do dict de parse_qsestão em uma lista, porque pode haver vários valores. Se você quer apenas o primeiro:

>>> 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
fonte
1
Isso não é exclusivo do Python 3, o Python 2 urllib.parse_qstambém retorna listas para os valores. Mencionei isso especificamente em minha resposta, por falar nisso, você pode querer usar em urllib.parse_qsl()vez disso e depois da lista resultante, dict()se quiser apenas valores únicos.
Martijn Pieters
Parece que a diferença com parse_qlsé que desde que ele retorna uma lista de tuplas, converter que para um dicionário irá manter o último valor em vez do primeiro . Isso, é claro, assume que havia vários valores para começar.
Reubano
11

Se você preferir não usar um analisador:

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("&") ]}

Portanto, não vou deletar o que está acima, mas definitivamente não é o que você deve usar.

Acho que li algumas das respostas e elas pareceram um pouco complicadas, caso você seja como eu, não use a minha solução.

Usa isto:

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

e para Python 2.X

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

Eu sei que esta é a mesma resposta aceita, apenas em uma linha que pode ser copiada.

Tomos Williams
fonte
6
A análise envolve mais do que apenas dividir a string. Você também precisa lidar com a codificação de URL (incluindo o +), e urllib.parsetambém levanta ou ignora erros para você, conforme solicitado. Não sei por que você deseja reinventar esta roda quando ela faz parte da biblioteca padrão.
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
fonte
4

Eu concordo em não reinventar a roda, mas às vezes (enquanto você está aprendendo) ajuda construir uma roda para entendê-la. :) Então, de uma perspectiva puramente acadêmica, ofereço isso com a ressalva de que o uso de um dicionário assume que os pares nome-valor são únicos (que a string de consulta não contém vários 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('&')]

Estou usando a versão 3.6.5 no Idle IDE.

Clarius
fonte
0

Pois python2.7estou usando o urlparsemódulo para analisar a consulta de url para dict.

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
fonte