Paramètres de requête d'URL pour dicter python

99

Existe-t-il un moyen d'analyser une URL (avec une bibliothèque python) et de renvoyer un dictionnaire python avec les clés et les valeurs d'une partie des paramètres de requête de l'URL?

Par exemple:

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

retour attendu:

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

Réponses:

189

Utilisez la urllib.parsebibliothèque :

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

Les méthodes urllib.parse.parse_qs()et urllib.parse.parse_qsl()analysent les chaînes de requête, en tenant compte du fait que les clés peuvent se produire plusieurs fois et que l'ordre peut avoir une importance.

Si vous êtes toujours sur Python 2, a urllib.parseété appelé urlparse.

Martijn Pieters
la source
37

Pour Python 3, les valeurs du dict from parse_qssont dans une liste, car il peut y avoir plusieurs valeurs. Si vous voulez juste le premier:

>>> 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
la source
1
Ce n'est pas unique à Python 3, Python 2 urllib.parse_qsrenvoie également des listes pour les valeurs. Je le mentionne spécifiquement dans ma réponse, au fait, vous voudrez peut-être utiliser à la urllib.parse_qsl()place et passer la liste résultante dict()si vous ne voulez que des valeurs uniques.
Martijn Pieters
On dirait que la différence avec parse_qlsest que puisqu'il retourne une liste de tuples, conversion qui un dict gardera la dernière valeur au lieu de la première . Cela suppose bien sûr qu'il y avait plusieurs valeurs pour commencer.
reubano
11

Si vous préférez ne pas utiliser d'analyseur:

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

Je ne supprimerai donc pas ce qui précède mais ce n'est certainement pas ce que vous devriez utiliser.

Je pense avoir lu quelques-unes des réponses et elles avaient l'air un peu compliquées, si vous êtes comme moi, n'utilisez pas ma solution.

Utilisez ceci:

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

et pour Python 2.X

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

Je sais que c'est la même chose que la réponse acceptée, juste dans une seule ligne qui peut être copiée.

Tomos Williams
la source
6
L'analyse implique plus que simplement diviser la chaîne. Vous devez également gérer le codage d'URL (y compris le +), et le urllib.parsedéclenche ou ignore également les erreurs pour vous, comme demandé. Je ne sais pas pourquoi vous voudriez réinventer cette roue lorsqu'elle fait partie de la bibliothèque standard.
Martijn Pieters
6

Pour 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
la source
4

Je suis d'accord pour ne pas réinventer la roue mais parfois (pendant que vous apprenez) cela aide à construire une roue pour comprendre une roue. :) Donc, d'un point de vue purement académique, je propose cela avec l'avertissement que l'utilisation d'un dictionnaire suppose que les paires nom-valeur sont uniques (que la chaîne de requête ne contient pas plusieurs enregistrements).

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

J'utilise la version 3.6.5 dans l'IDE Idle.

Clarius
la source
0

Car python2.7j'utilise le urlparsemodule pour analyser la requête d'url à 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
la source