我想知道我是否在python中规范化了一个URL。
例如,如果我有一个网址字符串,如:“http://www.example.com/foo goo / bar.html”
我需要一个python中的库,它会将额外空间(或任何其他非规范化字符)转换为正确的URL。
答案 0 :(得分:67)
看一下这个模块:werkzeug.utils。 (现在在werkzeug.urls
)
您正在寻找的功能称为“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))
答案 1 :(得分:57)
Real fix in Python 2.7 for that problem
正确的解决方案是:
# percent encode url, fixing lame server errors for e.g, like space
# within url paths.
fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]")
有关详细信息,请参阅Issue918368: "urllib doesn't correct server returned urls"
答案 2 :(得分:24)
使用urllib.quote
或urllib.quote_plus
引用(字符串[,安全])
替换字符串中的特殊字符 使用“%xx”转义。快报 数字和字符“_.-”是 从未引用过。可选的保险箱 参数指定其他 不应引用的字符 - 默认值为'/'。
示例:
quote('/~connolly/')
产生'/%7econnolly/'
。quote_plus(string [,safe])
与quote()类似,但也替换空格 按引号要求加号 HTML表单值。加上标志 原始字符串是转义的,除非 它们包含在安全中。它也是 安全默认为'/'。
编辑:在整个网址上使用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 and urlparse.urlunparse来解析url并仅对路径进行编码。这对你来说可能更有用,虽然如果你是从一个已知的协议和主机构建URL但是有一个可疑的路径,你可能也可以这样做以避免urlparse,只引用URL的可疑部分,连接到已知的安全部件。
答案 3 :(得分:12)
由于此页面是Google搜索该主题的最佳结果,因此我认为值得一提的是,使用Python进行的URL规范化已经完成了一些超出urlencoding空间字符的工作。例如,处理默认端口,字符大小写,缺少尾部斜杠等
在开发Atom联合格式时,有一些关于如何将URL规范化为规范格式的讨论;这在Atom / Pie wiki上的文章PaceCanonicalIds中有记录。那篇文章提供了一些很好的测试用例。
我相信这次讨论的结果之一是Mark Nottingham的urlnorm.py库,我在几个项目中使用了很好的结果。但是,该脚本不适用于此问题中给出的URL。因此,更好的选择可能是Sam Ruby's version of urlnorm.py,它处理该URL,以及来自Atom wiki的所有上述测试用例。
答案 4 :(得分:10)
import urlparse, urllib
def myquote(url):
parts= urlparse.urlparse(url)
return urlparse.urlunparse(parts[:2] + urllib.quote(parts[2]) + parts[3:])
这仅引用路径组件。
否则,你可以这样做:urllib.quote(url, safe=":/")
答案 5 :(得分:3)
仅供参考,urlnorm已移至github: http://gist.github.com/246089
答案 6 :(得分:1)
我遇到这样的问题:只需引用空格。
fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]")
可以提供帮助,但这太复杂了。
所以我用了一个简单的方法:url = url.replace(' ', '%20')
,它并不完美,但它是最简单的方法,适用于这种情况。
答案 7 :(得分:1)
适用于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