如何在python中规范化URL

Tom*_*ner 70 python url normalize normalization

我想知道我是否在python中规范化了一个URL.

例如,如果我有一个url字符串,如:" http://www.example.com/foo goo/bar.html"

我需要一个python中的库,它将额外的空间(或任何其他非规范化的字符)转换为正确的URL.

Arm*_*her 68

看看这个模块: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'
Run Code Online (Sandbox Code Playgroud)

它在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))
Run Code Online (Sandbox Code Playgroud)

  • `url_fix`现在位于`werkzeug.urls` (3认同)

Ole*_*rov 58

Python 2.7中针对该问题的真正修复

正确的解决方案是

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

有关更多信息,请参见Issue918368:"urllib无法更正服务器返回的URL"

  • 优秀的答案,简洁而有帮助.由于此更改位于urllib内,因此希望执行相同操作的代码应该是`import urllib`并使用上面的参数调用`urllib.quote()`. (4认同)

Bla*_*rad 24

urllib.quoteurllib.quote_plus

urllib文档:

quote(string [,safe])

使用"%xx"转义替换字符串中的特殊字符.从不引用字母,数字和字符"_.-".可选的安全参数指定不应引用的其他字符 - 其默认值为"/".

示例:quote('/~connolly/')收益率'/%7econnolly/'.

quote_plus(string [,safe])

与quote()类似,但也可以按引号替换空格,以引用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
Run Code Online (Sandbox Code Playgroud)

@ΤΖΩΤΖΙΟΥ提供了一个函数,它使用urlparse.urlparse和urlparse.urlunparse来解析url并仅对路径进行编码.这对你来说可能更有用,虽然如果你是从一个已知的协议和主机构建URL但是有一个可疑的路径,你可能也可以这样做以避免urlparse,只引用URL的可疑部分,连接到已知的安全部件.

  • 那么,给出问题的示例url,urllib.quote返回了什么? (2认同)

小智 13

由于此页面是Google搜索该主题的最佳结果,因此我认为值得一提的是,使用Python进行URL规范化的一些工作超出了urlencoding空格字符.例如,处理默认端口,字符大小写,缺少尾部斜杠等.

在开发Atom联合格式时,有一些关于如何将URL规范化为规范格式的讨论; 这在Atom/Pie wiki上的文章PaceCanonicalIds中有记载.该文章提供了一些很好的测试用例.

我相信这个讨论的一个结果是Mark Nottingham的urlnorm.py库,我在几个项目中使用了很好的结果.但是,该脚本不适用于此问题中给出的URL.因此,更好的选择可能是Sam Ruby的urlnorm.py版本,它处理该URL,以及来自Atom wiki的所有上述测试用例.


tzo*_*zot 9

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'
Run Code Online (Sandbox Code Playgroud)

这仅引用路径组件.

否则,您可以这样做: __CODE__

  • 这只是引用所有人物.这对他没有帮助. (2认同)