Python에서 지정된 URL에 매개 변수 추가
제게 URL이 주어졌다고 가정해 보겠습니다.
GET 변수 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()
읽기 전용이며 우리는 그것을 a로 변환해야 합니다.list
우리가 그것의 데이터를 수정하려고 시도하기 전에.
다음과 같이 작업할 것입니다.
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)
왜죠
저는 이 페이지의 모든 솔루션에 만족하지 못했기 때문에(자, 우리가 가장 좋아하는 복사 붙여넣기 방법은 어디에 있습니까?) 여기에 답변을 기반으로 저만의 솔루션을 작성했습니다.그것은 완전하고 더 피톤적이 되려고 노력합니다.저는 소비자 측(JS)에 더 친숙해지기 위해 인수에 딕트 및 쿨 값 처리기를 추가했지만, 아직 선택 사항이므로 삭제할 수 있습니다.
작동 방식
테스트 1: 새 인수 추가, 어레이 및 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'
테스트 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 = 'https://stackoverflow.com/test?answers=true'
>> new_params = {'answers': False, 'data': ['some','values']}
>> add_url_params(url, new_params)
'https://stackoverflow.com/test?data=some&data=values&answers=false'
"""
# Unquoting URL first so we don't lose 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 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'})
full 모듈 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
요청 lib를 사용하는 경우:
import requests
...
params = {'tag': 'python'}
requests.get(url, params=params)
이 답변을 기반으로 간단한 사례(파이썬 3 코드)를 위한 하나의 라이너:
from urllib.parse import urlparse, urlencode
url = "https://stackoverflow.com/search?q=question"
params = {'lang':'en','tag':'python'}
url += ('&' if urlparse(url).query else '?') + urlencode(params)
또는:
url += ('&', '?')[urlparse(url).query == ''] + urlencode(params)
저는 이것이 두 가지 주요 답변보다 더 우아하다고 생각합니다.
from urllib.parse import urlencode, urlparse, parse_qs
def merge_url_query_params(url: str, additional_params: dict) -> str:
url_components = urlparse(url)
original_params = parse_qs(url_components.query)
# Before Python 3.5 you could update original_params with
# additional_params, but here all the variables are immutable.
merged_params = {**original_params, **additional_params}
updated_query = urlencode(merged_params, doseq=True)
# _replace() is how you can create a new NamedTuple with a changed field
return url_components._replace(query=updated_query).geturl()
assert merge_url_query_params(
'http://example.com/search?q=question',
{'lang':'en','tag':'python'},
) == 'http://example.com/search?q=question&lang=en&tag=python'
상위 답변에서 제가 싫어하는 가장 중요한 것은 다음과 같습니다(그럼에도 불구하고 좋습니다).
- 우카시: 그 지수를 기억해야 합니다.
query
URL 구성 요소에 있습니다. - 된 Sapphire64를 : 업데트를만매장방법한황우드는.
ParseResult
제 반응의 나쁜 점은 마법처럼 보이는 것입니다.dict
압축 풀기를 사용하여 병합하지만, 가변성에 대한 편견 때문에 이미 존재하는 사전을 업데이트하는 것보다 더 선호합니다.
예: URLIB를 사용합니다.
설명서의 예를 참조하십시오.
>>> import urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
>>> print f.geturl() # Prints the final URL with parameters.
>>> print f.read() # Prints the contents
python3
자명한 일인 것 같습니다.
from urllib.parse import urlparse, urlencode, parse_qsl
url = 'https://www.linkedin.com/jobs/search?keywords=engineer'
parsed = urlparse(url)
current_params = dict(parse_qsl(parsed.query))
new_params = {'location': 'United States'}
merged_params = urlencode({**current_params, **new_params})
parsed = parsed._replace(query=merged_params)
print(parsed.geturl())
# https://www.linkedin.com/jobs/search?keywords=engineer&location=United+States
저는 우카시 버전을 좋아했지만, 이런 경우에 urllib와 urllparse 기능을 사용하기가 다소 어색하기 때문에, 다음과 같은 것을 하는 것이 더 간단하다고 생각합니다.
params = urllib.urlencode(params)
if urlparse.urlparse(url)[4]:
print url + '&' + params
else:
print url + '?' + params
다양한 기능을 사용하여 결합된 사전에서 기존 URL을 찢고,urlparse.urlunparse()
모든 것을 다시 정리하는 것.
아니면 그냥 결과물을 가져가세요.urllib.urlencode()
URL에 적절히 연결합니다.
하지만 또 다른 대답은:
def addGetParameters(url, newParams):
(scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
queryList = urlparse.parse_qsl(query, keep_blank_values=True)
for key in newParams:
queryList.append((key, newParams[key]))
return urlparse.urlunparse((scheme, netloc, path, params, urllib.urlencode(queryList), fragment))
python 2.5에서
import cgi
import urllib
import urlparse
def add_url_param(url, **params):
n=3
parts = list(urlparse.urlsplit(url))
d = dict(cgi.parse_qsl(parts[n])) # use cgi.parse_qs for list values
d.update(params)
parts[n]=urllib.urlencode(d)
return urlparse.urlunsplit(parts)
url = "http://stackoverflow.com/search?q=question"
add_url_param(url, lang='en') == "http://stackoverflow.com/search?q=question&lang=en"
제가 구현한 방법은 다음과 같습니다.
import urllib
params = urllib.urlencode({'lang':'en','tag':'python'})
url = ''
if request.GET:
url = request.url + '&' + params
else:
url = request.url + '?' + params
매력적으로 작동했습니다.하지만, 저는 이것을 구현할 수 있는 좀 더 깨끗한 방법을 원했을 것입니다.
위를 구현하는 또 다른 방법은 메소드에 넣는 것입니다.
import urllib
def add_url_param(request, **params):
new_url = ''
_params = dict(**params)
_params = urllib.urlencode(_params)
if _params:
if request.GET:
new_url = request.url + '&' + _params
else:
new_url = request.url + '?' + _params
else:
new_url = request.url
return new_ur
언급URL : https://stackoverflow.com/questions/2506379/add-params-to-given-url-in-python
'programing' 카테고리의 다른 글
압축된 파일을 Panda DataFrame으로 읽기 (0) | 2023.07.07 |
---|---|
텍스트의 언어를 결정하는 방법은 무엇입니까? (0) | 2023.07.02 |
인터페이스에 클래스 바인딩 (0) | 2023.07.02 |
조건을 기준으로 한 열 개수 (0) | 2023.07.02 |
'dplyr'의 새 열/변수에 동적 이름 사용 (0) | 2023.07.02 |