规范化/规范化URL?
我正在搜索一个库函数来规范Python中的URL,即删除路径中的“/”或“./”部分,或添加默认端口或转义特殊字符等。结果应该是一个字符串,该字符串对于指向同一网页的两个URL是唯一的。例如规范化/规范化URL?,url,python-3.x,normalization,Url,Python 3.x,Normalization,我正在搜索一个库函数来规范Python中的URL,即删除路径中的“/”或“./”部分,或添加默认端口或转义特殊字符等。结果应该是一个字符串,该字符串对于指向同一网页的两个URL是唯一的。例如http://google.com和http://google.com:80/a/../应返回相同的结果 我更喜欢Python3,并且已经浏览了urllib模块。它提供了拆分URL的功能,但没有提供规范化URL的功能。java有 URI .RealMeSeq()/Case>函数,它执行类似的操作(虽然它不考虑
http://google.com
和http://google.com:80/a/../
应返回相同的结果
我更喜欢Python3,并且已经浏览了urllib
模块。它提供了拆分URL的功能,但没有提供规范化URL的功能。java有<代码> URI .RealMeSeq()/Case>函数,它执行类似的操作(虽然它不考虑默认端口80等于给定端口),但有类似这样的东西吗?Python?< /P> < P>
In [1]: from urllib.parse import urljoin
In [2]: urljoin('http://example.com/a/b/c/../', '.')
Out[2]: 'http://example.com/a/b/'
灵感来源于对问题的回答。它不会规范化端口,但启动一个函数应该很简单。在之后,我编写了一个方法,适用于web中常见的大多数情况
def urlnorm(base, link=''):
'''Normalizes an URL or a link relative to a base url. URLs that point to the same resource will return the same string.'''
new = urlparse(urljoin(base, url).lower())
return urlunsplit((
new.scheme,
(new.port == None) and (new.hostname + ":80") or new.netloc,
new.path,
new.query,
''))
这就是我所用的,到目前为止一直有效。你可以从pip那里得到URLMORM 请注意,我对查询参数进行了排序。我发现这很重要
from urlparse import urlsplit, urlunsplit, parse_qsl
from urllib import urlencode
import urlnorm
def canonizeurl(url):
split = urlsplit(urlnorm.norm(url))
path = split[2].split(' ')[0]
while path.startswith('/..'):
path = path[3:]
while path.endswith('%20'):
path = path[:-3]
qs = urlencode(sorted(parse_qsl(split.query)))
return urlunsplit((split.scheme, split.netloc, path, qs, ''))
旧(不赞成的)答案
[不再维护]模块规范化多个斜杠、
和。
组件,而不会弄乱http://
中的双斜杠
一旦您执行了pip安装urltools
(由于作者重命名了repo,这不再有效),用法如下:
print urltools.normalize('http://example.com:80/a////b/../c')
>>> 'http://example.com/a/c'
虽然模块不再是pip可安装的,但它是可重复使用的
Python3的最新答案
Python 3考虑从模块中使用。
从urllib.parse导入urljoin
urljoin('https://stackoverflow.com/questions/10584861/“,”../dinsdale')
#Out[17]:'https://stackoverflow.com/questions/dinsdale'
现在有一个专门针对这个问题的库
它不仅仅是按照文档规范化路径:
URI规范化函数:
from url_normalize import url_normalize
url = 'http://google.com:80/a/../'
print(url_normalize(url))
其中:
http://google.com/
我在上面使用了@Antony的答案并使用了库,但它有一个目前尚未修复的错误:当发送URL时没有方案,is会意外地将其设置为HTTPS。我编写了一个函数,通过将其改为HTTP来包装和修复它:
from url_normalize import url_normalize
from urllib.parse import urlparse
def parse_url(url):
return_val = url_normalize(url)
wrong_default_prefix = "https://"
new_default_prefix = "http://"
# If the URL came with no scheme and the normalize function mistakenly
# set it to the HTTPS protocol, then fix it and set it to HTTP
if urlparse(url).scheme.strip() == '' and return_val.startswith(wrong_default_prefix):
return_val = new_default_prefix + return_val[len(wrong_default_prefix):]
return return_val
我没有
urllib.parse
,但我有urlprase
urllib.parse
是Python 3的位置-最初的问题是关于Py 3的。这在任何不以“/”结尾的地方都会非常失败,删除无效的父目录您需要替换split[2]。split(“”)[0]
带有urllib.parse.quote(split[2])
——在某些情况下,URL中有空格是完全正常的,事实上是必需的。另外,urlnorm是py2konly,因此,在一些不寻常的情况下,您将丢弃片段,它实际上可能是必需的URL组件。是的,有非零数量的网页,blah.com/#wat
与blah.com/
是完全不同的页面。它通常是用javascript完成的,是一个巨大的PITA,但它是存在的。@FakeName写道:“URL中有空格是完全正常的,事实上是必需的。”。不,那是绝对错误的。URL中不允许使用空格。阅读规范:一些浏览器错误地显示空格,但事实上它们是百分比编码的http://google.com/与http://google.com:80/a/../
。也就是说,如果/a
不存在,则第二条路径将失败。通过“规范化”它,您将丢失这种特殊情况,并在开始使用无效URI时使用有效URI…这是不正确的,无论如何在浏览器中都不正确。即使a不存在,您也可以编写,它将转到。这是因为浏览器在发送到服务器之前进行初始解析。在服务器端,不同的服务器以不同的方式运行。https呢?很好!唯一不能正常工作的是,当不提供协议时,它返回HTTPS而不是HTTP。示例网站转到“https:////example.com“@GilCohen,https是目前推荐的做法,因此这种行为可能是故意的。例如,请参阅和。理论上您可能是正确的,但在实践中,当协议没有规定时,浏览器会先尝试HTTP。urltools似乎已经离开了地球。没有github,没有pypi,任何地方都没有缓存副本。如果有人知道发生了什么,请告诉我。@GaneshKathiresan:看来作者决定重新命名回购协议;更新