web-dev-qa-db-fra.com

Python-Requests, extraire les paramètres d'url d'une chaîne

J'utilise cette bibliothèque géniale appelée requests pour maintenir la compatibilité python 2 & 3 et simplifier la gestion de mes demandes d'application.

J'ai un cas où j'ai besoin d'analyser une URL et de remplacer l'un de ses paramètres. Par exemple:

http://example.com?param1=a&token=TOKEN_TO_REPLACE&param2=c

Et je veux obtenir ceci:

http://example.com?param1=a&token=NEW_TOKEN&param2=c

Avec le urllib je peux y arriver de cette façon:

from urllib.parse import urlparse
from urllib.parse import parse_qs
from urllib.parse import urlencode

url = 'http://example.com?param1=a&token=TOKEN_TO_REPLACE&param2=c'

o = urlparse(url)
query = parse_qs(o.query)
if query.get('token'):
    query['token'] = ['NEW_TOKEN', ]
    new_query = urlencode(query, doseq=True)
    url.split('?')[0] + '?' + new_query

>>> http://example.com?param2=c&param1=a&token=NEW_TOKEN

Comment pouvez-vous obtenir le même résultat en utilisant la bibliothèque requests?

16
Gab

Vous ne pouvez pas utiliser requests pour cela; la bibliothèque builds ces URL si passé une structure Python pour les paramètres, mais ne propose pas d'outils pour les analyser. Ce n'est pas un objectif du projet.

Tenez-vous au urllib.parse méthode pour analyser les paramètres. Une fois que vous avez un dictionnaire ou une liste de tuples de valeurs-clés, passez-le simplement à requests pour reconstruire l'URL:

try:
    # Python 3
    from urllib.parse import urlparse, parse_qs
except ImportError:
    # Python 2
    from urlparse import urlparse, parse_qs

o = urlparse(url)
query = parse_qs(o.query)
# extract the URL without query parameters
url = o._replace(query=None).geturl()

if 'token' in query:
    query['token'] = 'NEW_TOKEN'

requests.get(url, params=query)

Vous pouvez obtenir à la fois urlparse et parse_qs fonctions dans les deux Python 2 et 3, tout ce que vous avez à faire est d'ajuster l'emplacement d'importation si vous obtenez une exception.

Démo sur Python 3 (sans le garde d'exception d'importation) pour montrer que l'URL a été construite:

>>> from urllib.parse import urlparse, parse_qs
>>> url = "http://httpbin.org/get?token=TOKEN_TO_REPLACE&param2=c"
>>> o = urlparse(url)
>>> query = parse_qs(o.query)
>>> url = o._replace(query=None).geturl()
>>> if 'token' in query:
...     query['token'] = 'NEW_TOKEN'
... 
>>> response = requests.get(url, params=query)
>>> print(response.text)
{
  "args": {
    "param2": "c", 
    "token": "NEW_TOKEN"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.5.1 CPython/3.4.2 Darwin/14.1.0"
  }, 
  "Origin": "188.29.165.245", 
  "url": "http://httpbin.org/get?token=NEW_TOKEN&param2=c"
}
42
Martijn Pieters

Utilisation de requests uniquement:

query = requests.utils.urlparse(url).query
params = dict(x.split('=') for x in query.split('&'))

if 'token' in params:
    params['token'] = 'NEW_TOKEN'

requests.get(url, params=params)
7
Dorik1972