ProgramingTip

어디에서 URL을 어떻게 정규화 할 수 있습니까?

bestdevel 2020. 10. 31. 09:56
반응형

어디에서 URL을 어떻게 정규화 할 수 있습니까?


어떤 URL을 정규화하는지 알고 싶습니다.

예를 들어 " http://www.example.com/foo goo / bar.html" 과 같은 URL이있는 경우

존재의 필요 공간 (또는 기타 정규화되지 않은 문자)을 적절한 URL로 변환하는 라이브러리가 있습니다.


이 모듈을 사용합니다 : werkzeug.utils . (현재 werkzeug.urls)

찾고있는 함수는 "url_fix"라고하며 다음과 같이 작동합니다.

>>> from werkzeug.urls import url_fix
>>> url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)')
'http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29'

Werkzeug에서 다음과 같이 구현됩니다.

import urllib
import urlparse

def url_fix(s, charset='utf-8'):
    """Sometimes you get an URL by a user that just isn't a real
    URL because it contains unsafe characters like ' ' and so on.  This
    function can fix some of the problems in a similar way browsers
    handle data entered by the user:

    >>> url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)')
    'http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29'

    :param charset: The target charset for the URL if the url was
                    given as unicode string.
    """
    if isinstance(s, unicode):
        s = s.encode(charset, 'ignore')
    scheme, netloc, path, qs, anchor = urlparse.urlsplit(s)
    path = urllib.quote(path, '/%')
    qs = urllib.quote_plus(qs, ':&=')
    return urlparse.urlunsplit((scheme, netloc, path, qs, anchor))

해당 문제에 대한 Python 2.7의 실제 수정

올바른 솔루션은 다음과 달라집니다.

 # percent encode url, fixing lame server errors for e.g, like space
 # within url paths.
 fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]")

내용은 Issue918368 : "urllib에서 서버 반환 URL을 수정하지 않음"을 참조하십시오 .


사용 urllib.quote또는urllib.quote_plus

URLLIB 문서 :

따옴표 (문자열 [, 안전])

"% xx"이스케이프를 사용하여 언어의 특수 문자를 바꿉니다. 문자, 숫자 및 문자 "_.-"는 인용되지 않습니다. 고유 한 고유 변수는 따옴표로 묶지 추가 문자를 지정합니다. 상관은 '/'입니다.

예 : quote('/~connolly/')수율 '/%7econnolly/'.

quote_plus (문자열 [, 안전])

인용 ()과 미래하지만 HTML 양식 값을 인용하는 데 필요에 따라 공백을 더하기 기호로 바꿉니다. 원래의 더하기 기호는 금고에 포함되지 않는 한 이스케이프 처리됩니다. 또한 '/'에 대한 안전한 저장이 없습니다.

편집 : 전체 URL에 urllib.quote 또는 urllib.quote_plus를 사용하면 @ ΤΖΩΤΖΙΟΥ이 지적한 것처럼 엉망이됩니다.

>>> quoted_url = urllib.quote('http://www.example.com/foo goo/bar.html')
>>> quoted_url
'http%3A//www.example.com/foo%20goo/bar.html'
>>> urllib2.urlopen(quoted_url)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python25\lib\urllib2.py", line 124, in urlopen
    return _opener.open(url, data)
  File "c:\python25\lib\urllib2.py", line 373, in open
    protocol = req.get_type()
  File "c:\python25\lib\urllib2.py", line 244, in get_type
    raise ValueError, "unknown url type: %s" % self.__original
ValueError: unknown url type: http%3A//www.example.com/foo%20goo/bar.html

@ ΤΖΩΤΖΙΟΥ는 urlparse.urlparse 및 urlparse.urlunparse사용 하여 URL을 구문 분석하고 경로 만 인코딩 하는 함수를 제공합니다 . 이 방법이 더 유용 할 수 있지만 알려진 프로토콜 및 호스트에서 URL을 작성하지만 의심스러운 경로가있는 경우 urlparse를 방지하고 URL의 의심스러운 부분을 인용하여 다음과 연결할 수도 있습니다. 알려진 안전 부품.


이 페이지는 해당 주제에 대한 Google 검색의 상위 결과이기 때문에 공백 문자를 urlencoding을 넘어선 Python으로 URL 정규화에 대해 수행 한 작업을 언급 할 가치가 있다고 생각합니다. 예를 들어, 기본 포트, 문자 대소 문자, 후행 슬래시 부족 등을 처리합니다.

Atom 신디케이션 형식이 개발 될 때 URL을 표준 형식으로 정규화하는 방법에 대한 논의가있었습니다. 이것은 Atom / Pie wiki의 PaceCanonicalIds 기사에 설명 되어 있습니다. 이 기사는 좋은 테스트 케이스를 제공합니다.

저는이 토론의 결과 중 하나가 Mark Nottingham의 urlnorm.py 라이브러리 라고 믿습니다.이 라이브러리는 몇 가지 프로젝트에서 좋은 결과를 얻었습니다. 그러나 해당 스크립트는이 질문에 제공된 URL에서 작동하지 않습니다. 따라서 더 나은 선택은 해당 URL을 처리하는 Sam Ruby의 urlnorm.py 버전 과 앞서 언급 한 Atom 위키의 모든 테스트 사례 일 수 있습니다.


Py3

from urllib.parse import urlparse, urlunparse, quote
def myquote(url):
    parts = urlparse(url)
    return urlunparse(parts._replace(path=quote(parts.path)))

>>> myquote('https://www.example.com/~user/with space/index.html?a=1&b=2')
'https://www.example.com/~user/with%20space/index.html?a=1&b=2'

Py2

import urlparse, urllib
def myquote(url):
    parts = urlparse.urlparse(url)
    return urlparse.urlunparse(parts[:2] + (urllib.quote(parts[2]),) + parts[3:])

>>> myquote('https://www.example.com/~user/with space/index.html?a=1&b=2')
'https://www.example.com/%7Euser/with%20space/index.html?a=1&b=2'

경로 구성 요소 만 인용합니다.


참고로 urlnorm이 github로 이동했습니다 : http://gist.github.com/246089


Python 3.5에 해당 :

import urllib.parse

urllib.parse.quote([your_url], "\./_-:")

예:

import urllib.parse

print(urllib.parse.quote("http://www.example.com/foo goo/bar.html", "\./_-:"))

출력은 http://www.example.com/foo%20goo/bar.html입니다.

글꼴 : https://docs.python.org/3.5/library/urllib.parse.html?highlight=quote#urllib.parse.quote


그런 문제가 발생했습니다. 공백 만 인용하면됩니다.

fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]") 도와 주지만 너무 복잡합니다.

그래서 저는 간단한 방법을 사용했습니다. url = url.replace(' ', '%20')완벽하지는 않지만 가장 간단한 방법이며이 상황에서 작동합니다.

참고 URL : https://stackoverflow.com/questions/120951/how-can-i-normalize-a-url-in-python

반응형