Parametry zapytania URL do podyktowania języka Python

101

Czy istnieje sposób na przeanalizowanie adresu URL (za pomocą jakiejś biblioteki Pythona) i zwrócenie słownika Pythona z kluczami i wartościami części adresu URL zawierającej parametry zapytania?

Na przykład:

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

spodziewany powrót:

{'ct':32, 'op':92, 'item':98}
Leonardo Andrade
źródło

Odpowiedzi:

191

Skorzystaj z urllib.parsebiblioteki :

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

urllib.parse.parse_qs()I urllib.parse.parse_qsl()metody analizowania się ciągi zapytań, biorąc pod uwagę, że klucze mogą wystąpić więcej niż jeden raz i że zamówienie może znaczenia.

Jeśli nadal korzystasz z Pythona 2, urllib.parsezostał wywołany urlparse.

Martijn Pieters
źródło
38

W przypadku Pythona 3 wartości polecenia z parse_qsznajdują się na liście, ponieważ może istnieć wiele wartości. Jeśli chcesz tylko pierwszy:

>>> 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
źródło
1
Nie jest to unikalne dla Pythona 3, Python 2 urllib.parse_qsrównież zwraca listy wartości. Wspominam o tym konkretnie w mojej odpowiedzi, przy okazji, możesz chcieć użyć urllib.parse_qsl()zamiast wynikowej listy do, dict()jeśli chcesz tylko pojedyncze wartości.
Martijn Pieters
Wygląda na parse_qlsto, że różnica polega na tym, że ponieważ zwraca listę krotek, konwersja tego na dyktę zachowa ostatnią wartość zamiast pierwszej . To oczywiście zakłada, że ​​na początku było wiele wartości.
reubano
11

Jeśli wolisz nie używać parsera:

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

Więc nie będę usuwał tego, co powyżej, ale zdecydowanie nie jest to, czego powinieneś używać.

Myślę, że przeczytałem kilka odpowiedzi i wyglądały na trochę skomplikowane, jeśli jesteś podobny do mnie, nie używaj mojego rozwiązania.

Użyj tego:

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

i dla Pythona 2.X

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

Wiem, że to to samo, co zaakceptowana odpowiedź, tylko w jednej linijce, którą można skopiować.

Tomos Williams
źródło
7
Parsowanie to coś więcej niż tylko dzielenie łańcucha. Musisz także obsłużyć kodowanie adresów URL (w tym +), a urllib.parsetakże podnosi lub ignoruje błędy zgodnie z żądaniem. Nie jestem pewien, dlaczego chciałbyś wymyślić to koło na nowo, skoro jest częścią standardowej biblioteki.
Martijn Pieters
6

W przypadku Pythona 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
źródło
5

Zgadzam się, że nie trzeba wymyślać koła na nowo, ale czasami (podczas nauki) pomaga zbudować koło, aby zrozumieć koło. :) Tak więc, z czysto akademickiego punktu widzenia, proponuję to z zastrzeżeniem, że używanie słownika zakłada, że ​​pary nazwa-wartość są unikalne (że ciąg zapytania nie zawiera wielu rekordów).

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

Używam wersji 3.6.5 w Idle IDE.

Clarius
źródło
0

Ponieważ python2.7używam urlparsemodułu do analizowania zapytania URL do dyktowania.

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
źródło