Python:如何解析包含';的URL';
我需要唯一地标识和存储一些URL。问题是有时它们包含“.”如Python:如何解析包含';的URL';,python,url,Python,Url,我需要唯一地标识和存储一些URL。问题是有时它们包含“.”如http://somedomain.com/foo/bar/../../some/url基本上是http://somedomain.com/some/url如果我没有错的话 是否有Python函数或棘手的方法来解析此URL?这些是文件路径。看看: 编辑: 如果在Windows上,则输入路径将使用反斜杠而不是斜杠。在这种情况下,您仍然需要os.path.normpath来摆脱。模式(以及/和/./以及任何其他多余的模式),然后将反斜杠转换
http://somedomain.com/foo/bar/../../some/url
基本上是http://somedomain.com/some/url
如果我没有错的话
是否有Python函数或棘手的方法来解析此URL?这些是文件路径。看看: 编辑: 如果在Windows上,则输入路径将使用反斜杠而不是斜杠。在这种情况下,您仍然需要
os.path.normpath
来摆脱。
模式(以及/
和/./
以及任何其他多余的模式),然后将反斜杠转换为正斜杠:
def fix_path_for_URL(path):
result = os.path.normpath(path)
if os.sep == '\\':
result = result.replace('\\', '/')
return result
编辑2:
如果要规范化URL,请使用模块进行规范化(在剥离方法等之前),如中所示
编辑3:
似乎urljoin
没有规范化给定的基本路径:
>>> import urlparse
>>> urlparse.urljoin('http://somedomain.com/foo/bar/../../some/url', '')
'http://somedomain.com/foo/bar/../../some/url'
normpath
本身也不能完全切断它:
>>> import os
>>> os.path.normpath('http://somedomain.com/foo/bar/../../some/url')
'http:/somedomain.com/some/url'
注意,最初的双斜杠被吃掉了
因此,我们必须让他们联合起来:
def fix_URL(urlstring):
parts = list(urlparse.urlparse(urlstring))
parts[2] = os.path.normpath(parts[2].replace('/', os.sep)).replace(os.sep, '/')
return urlparse.urlunparse(parts)
用法:
>>> fix_URL('http://somedomain.com/foo/bar/../../some/url')
'http://somedomain.com/some/url'
有一个简单的解决方案,使用: 但是,如果没有尾随斜杠(最后一个组件是文件,而不是目录),最后一个组件将被删除 此修复程序使用urlparse函数提取路径,然后使用(的posixpath版本)规范化组件。补偿,然后将URL重新连接在一起。以下是
doctest
able:
from urllib.parse import urlparse
import posixpath
def resolve_components(url):
"""
>>> resolve_components('http://www.example.com/foo/bar/../../baz/bux/')
'http://www.example.com/baz/bux/'
>>> resolve_components('http://www.example.com/some/path/../file.ext')
'http://www.example.com/some/file.ext'
"""
parsed = urlparse(url)
new_path = posixpath.normpath(parsed.path)
if parsed.path.endswith('/'):
# Compensate for issue1707768
new_path += '/'
cleaned = parsed._replace(path=new_path)
return cleaned.geturl()
我想评论一下顶部响应中的
resolveComponents
函数
请注意,如果您的路径是/
,则代码将添加另一个可能有问题的路径。
因此,我将IF
条件更改为:
if parsed.path.endswith( '/' ) and parsed.path != '/':
根据这一点,这应该是“相对解决”过程的一部分。所以答案可能是urlparse.urljoin(url,”)
。但由于错误,当第二个参数为空url时,urlparse.urljoin不会删除点段。您可以使用-alternative url操纵库。它正确地做到了这一点:
>>> import yurl
>>> print yurl.URL('http://somedomain.com/foo/bar/../../some/url') + yurl.URL()
http://somedomain.com/some/url
urljoin
不起作用,因为它只在第二个参数不是绝对(!?)或空时解析点段。不仅如此,它不会根据正确地处理过多的。
s(它们应该被删除;urljoin
不会这样做)posixpath.normpath
也不能使用(更不用说os.path.normpath)
,因为它将一行中的多个斜杠解析为一个斜杠(例如/////code>变成///code>),这对于URL来说是不正确的行为
下面的短函数正确解析任何URL路径字符串。但是,它不应与相对路径一起使用,因为需要对其行为做出其他决定(在过多的上引发错误)。
s?在开始时删除
?将两者都保留?)-相反,如果知道可以处理相对路径,请在解析之前连接URL。不言而喻:
def resolve_url_path(path):
segments = path.split('/')
segments = [segment + '/' for segment in segments[:-1]] + [segments[-1]]
resolved = []
for segment in segments:
if segment in ('../', '..'):
if resolved[1:]:
resolved.pop()
elif segment not in ('./', '.'):
resolved.append(segment)
return ''.join(resolved)
这将正确处理尾随点段(即,没有尾随斜杠)和连续斜杠。要解析整个URL,您可以使用以下包装器(或者只将路径解析函数内联到其中)
你可以这样称呼它:
>>> resolve_url('http://example.com/../thing///wrong/../multiple-slashes-yeah/.')
'http://example.com/thing///multiple-slashes-yeah/'
事实证明,正确的URL解析有很多陷阱 导入URL解析
导入posixpath
parsed=list(urlparse.urlparse(url))
已解析[2]=posixpath.normpath(posixpath.join(已解析[2],rel_path))
正确的url=urlparse.urlparse(已解析)
URL。我把它们放在这里是因为我把它们放在了域名、方案等的后面……请看@jledev:这对我不起作用。“.”的数字可以不同,并且在URL中的不同位置。这甚至不起作用:urlparse.urljoin(“,“/…”)在我的机器上喊“.”|@Nicolae将其更改为。/..
工作;我会纠正的。至少Firefox,而且,我想,所有体面的浏览器都不会发送这种风格的请求——他们会自己解释../的。就我个人而言,我会忽略这些URL或发送400错误请求
。请注意,“在Windows上,它会将正向斜杠转换为反向斜杠。”这几乎是完美的,但可能我的问题不够具体(我已编辑以更恰当地反映这一点):这些是URL,我刚刚省略了域名和架构。这将路径/foo/bar/./../some/url'
转换为python 3中mac上的/some/url
。太棒了!效果很好。万分感谢!您也应该保留旧示例,并将其添加为编辑,因为这纯粹是一个了不起的例子,也许它会帮助其他可怜的灵魂幸运的是,如果URL中有太多。
,这似乎不起作用。e、 g.urljoin('http://x.com/../index.html“,”。)
->'http://x.com/../“
而不是正确的”http://x.com/index.html遗憾的是,如果第二个组件是绝对的,则'
urljoin
也不起作用。例如,urljoin(“http://example.com/blah.html“,”//whoa.html“
会删除点,而urljoin(”http://example.com/blah.html“,”/././//whoa.html“
不会。哦,还有,posixpath.normpath
规范化了几个斜杠(例如“///code>)根据RFC和浏览器的实现,这种情况不应该发生。“它不会正确地处理过多的。
s”-在Python 3.5(但不是2.7)和3.4上都会发生:(你能详细解释一下为什么//
变成/
对URL来说是不正确的行为吗?我浏览了全文,找到了关键字/
,但找不到任何他们认为路径中相邻的斜杠有意义的东西,例如/
。@raylo看一看
def resolve_url_path(path):
segments = path.split('/')
segments = [segment + '/' for segment in segments[:-1]] + [segments[-1]]
resolved = []
for segment in segments:
if segment in ('../', '..'):
if resolved[1:]:
resolved.pop()
elif segment not in ('./', '.'):
resolved.append(segment)
return ''.join(resolved)
try:
# Python 3
from urllib.parse import urlsplit, urlunsplit
except ImportError:
# Python 2
from urlparse import urlsplit, urlunsplit
def resolve_url(url):
parts = list(urlsplit(url))
parts[2] = resolve_url_path(parts[2])
return urlunsplit(parts)
>>> resolve_url('http://example.com/../thing///wrong/../multiple-slashes-yeah/.')
'http://example.com/thing///multiple-slashes-yeah/'