Mengapa
Saya belum puas dengan semua solusi di halaman ini ( ayolah, di mana hal salin-tempel favorit kami? ) Jadi saya menulis sendiri berdasarkan jawaban di sini. Ia mencoba untuk menjadi lengkap dan lebih Pythonic. Saya telah menambahkan penangan untuk nilai dict dan bool dalam argumen agar lebih bersahabat dengan sisi konsumen ( JS ), tetapi mereka masih opsional, Anda dapat melepaskannya.
Bagaimana itu bekerja
Tes 1: Menambahkan argumen baru, menangani nilai Array dan Bool:
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'
Tes 2: Menulis ulang argumen yang ada, menangani nilai 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'
Berbicara itu murah. Tunjukkan kodenya.
Kode itu sendiri. Saya sudah mencoba menjelaskannya secara rinci:
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
Perlu diketahui bahwa mungkin ada beberapa masalah, jika Anda akan menemukannya, beri tahu saya dan kami akan membuatnya lebih baik
urlparse.parse_qs
bukanparse_qsl
. Yang terakhir mengembalikan daftar sedangkan Anda menginginkan dikt. Lihat docs.python.org/library/urlparse.html#urlparse.parse_qs .