URL을 받았다고 가정합니다.
이미 GET 매개 변수 (예 :)가 http://example.com/search?q=question
있거나 없을 수 있습니다 (예 :http://example.com/
.
이제 몇 가지 매개 변수를 추가해야합니다 {'lang':'en','tag':'python'}
. 첫 번째 경우에는, 두 번째 경우에는 http://example.com/search?q=question&lang=en&tag=python
— http://example.com/search?lang=en&tag=python
.
이를 수행하는 표준 방법이 있습니까?
답변
urllib
및 urlparse
모듈 에는 몇 가지 단점이 있습니다. 다음은 작동하는 예입니다.
try:
import urlparse
from urllib import urlencode
except: # For Python 3
import urllib.parse as urlparse
from urllib.parse import urlencode
url = "http://stackoverflow.com/search?q=question"
params = {'lang':'en','tag':'python'}
url_parts = list(urlparse.urlparse(url))
query = dict(urlparse.parse_qsl(url_parts[4]))
query.update(params)
url_parts[4] = urlencode(query)
print(urlparse.urlunparse(url_parts))
ParseResult
의 결과는 urlparse()
, 읽기 전용입니다 그리고 우리는 그것을 변환해야 list
우리가 데이터를 수정하려고하기 전에.
답변
왜
이 페이지의 모든 솔루션에 만족하지 못했기 때문에 (자 , 우리가 가장 좋아하는 복사-붙여 넣기는 어디에 있습니까? ) 여기에 답변을 기반으로 직접 작성했습니다. 그것은 완전하고 더 Pythonic하려고 노력합니다. 소비자 측이되기 위해 인수 에 dict 및 bool 값에 대한 처리기를 추가했습니다 ( JS ) 친화적 인 했지만 아직 선택 사항이므로 삭제할 수 있습니다.
작동 원리
테스트 1 : 새 인수 추가, 배열 및 부울 값 처리 :
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'
테스트 2 : 기존 인수 다시 쓰기, 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'
대화는 저렴합니다. 코드를 보여주세요.
코드 자체. 나는 그것을 자세히 설명하려고 노력했습니다.
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
몇 가지 문제가있을 수 있습니다. 문제를 찾으면 알려 주시면이 문제를 개선하겠습니다.
답변
문자열에 임의의 데이터가있을 수있는 경우 URL 인코딩을 사용하려고합니다 (예 : 앰퍼샌드, 슬래시 등의 문자를 인코딩해야 함).
urllib.urlencode를 확인하십시오.
>>> import urllib
>>> urllib.urlencode({'lang':'en','tag':'python'})
'lang=en&tag=python'
python3에서 :
from urllib import parse
parse.urlencode({'lang':'en','tag':'python'})
답변
furl 모듈 https://github.com/gruns/furl을 사용할 수도 있습니다.
>>> from furl import furl
>>> print furl('http://example.com/search?q=question').add({'lang':'en','tag':'python'}).url
http://example.com/search?q=question&lang=en&tag=python
답변
전투 테스트 요청 라이브러리에 아웃소싱 .
이것이 내가 할 방법입니다.
from requests.models import PreparedRequest
url = 'http://example.com/search?q=question'
params = {'lang':'en','tag':'python'}
req = PreparedRequest()
req.prepare_url(url, params)
print(req.url)
답변
requests lib를 사용하는 경우 :
import requests
...
params = {'tag': 'python'}
requests.get(url, params=params)