Pourquoi
Je n'ai pas été satisfait de toutes les solutions sur cette page ( allez, où est notre chose préférée de copier-coller? ) Alors j'ai écrit la mienne en fonction des réponses ici. Il essaie d'être complet et plus pythonique. J'ai ajouté un gestionnaire pour les valeurs dict et booléen dans les arguments pour être plus convivial côté consommateur ( JS ), mais ils sont encore facultatifs, vous pouvez les supprimer.
Comment ça fonctionne
Test 1: Ajout de nouveaux arguments, gestion des tableaux et des valeurs booléennes:
url = 'http://stackoverflow.com/test'
new_params = {'answers': False, 'data': ['some','values']}
add_url_params(url, new_params) == \
'http://stackoverflow.com/test?data=some&data=values&answers=false'
Test 2: réécriture d'arguments existants, gestion des valeurs DICT:
url = 'http://stackoverflow.com/test/?question=false'
new_params = {'question': {'__X__':'__Y__'}}
add_url_params(url, new_params) == \
'http://stackoverflow.com/test/?question=%7B%22__X__%22%3A+%22__Y__%22%7D'
Parler n'est pas cher. Montre-moi le code.
Code lui-même. J'ai essayé de le décrire en détail:
from json import dumps
try:
from urllib import urlencode, unquote
from urlparse import urlparse, parse_qsl, ParseResult
except ImportError:
# Python 3 fallback
from urllib.parse import (
urlencode, unquote, urlparse, parse_qsl, ParseResult
)
def add_url_params(url, params):
""" Add GET params to provided URL being aware of existing.
:param url: string of target URL
:param params: dict containing requested params to be added
:return: string with updated URL
>> url = 'http://stackoverflow.com/test?answers=true'
>> new_params = {'answers': False, 'data': ['some','values']}
>> add_url_params(url, new_params)
'http://stackoverflow.com/test?data=some&data=values&answers=false'
"""
# Unquoting URL first so we don't loose existing args
url = unquote(url)
# Extracting url info
parsed_url = urlparse(url)
# Extracting URL arguments from parsed URL
get_args = parsed_url.query
# Converting URL arguments to dict
parsed_get_args = dict(parse_qsl(get_args))
# Merging URL arguments dict with new params
parsed_get_args.update(params)
# Bool and Dict values should be converted to json-friendly values
# you may throw this part away if you don't like it :)
parsed_get_args.update(
{k: dumps(v) for k, v in parsed_get_args.items()
if isinstance(v, (bool, dict))}
)
# Converting URL argument to proper query string
encoded_get_args = urlencode(parsed_get_args, doseq=True)
# Creating new parsed result object based on provided with new
# URL arguments. Same thing happens inside of urlparse.
new_url = ParseResult(
parsed_url.scheme, parsed_url.netloc, parsed_url.path,
parsed_url.params, encoded_get_args, parsed_url.fragment
).geturl()
return new_url
Sachez qu'il peut y avoir des problèmes, si vous en trouvez un, faites-le moi savoir et nous améliorerons cette chose
urlparse.parse_qs
place deparse_qsl
. Ce dernier renvoie une liste alors que vous voulez un dict. Voir docs.python.org/library/urlparse.html#urlparse.parse_qs .