我正在制作一个需要从拖放输入中读取 URI 的应用程序。我正在尝试使用 urllib.parse.urlparse()
处理每个 URI .
urlparse()
按预期处理 Internet URL:
>>> import urllib
>>> urllib.parse.urlparse('https://www.google.com/advanced_search')
ParseResult(scheme='https', netloc='www.google.com', path='/advanced_search', params='', query='', fragment='')
但是在本地 Windows 文件上使用它会在路径的开头留下一个额外的斜线:
>>> urllib.parse.urlparse('file:///C:/Program%20Files/Python36/LICENSE.txt')
ParseResult(scheme='file', netloc='', path='/C:/Program%20Files/Python36/LICENSE.txt', params='', query='', fragment='')
事实上,需要本地文件路径的函数似乎不喜欢这个额外的斜线:
>>> from pathlib import Path
>>> Path('/C:/Program%20Files/Python36/LICENSE.txt').exists()
Traceback (most recent call last):
...
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: '\\C:\\Program%20Files\\Python36\\LICENSE.txt'
我可以自己编写一个特例来处理 file:///<Windows drive letter>:
不知何故,但作为一个清洁问题:是否有更好的 Python 函数来一般地拆分 URI,而不仅仅是 URL?还是我还缺少其他东西?
使用 Python 3.6.1。
最佳答案
使用 urllib.request.url2pathname()
在路径组件上将去除 Windows 的开始斜线。
>>> import urllib
>>> import urllib.request
>>> path = urllib.parse.urlparse('file:///C:/Program%20Files/Python36/LICENSE.txt').path
>>> path
'/C:/Program%20Files/Python36/LICENSE.txt'
>>> urllib.request.url2pathname(path)
'C:\\Program Files\\Python36\\LICENSE.txt'
所以我的 URI 处理应用程序应该使用 url2pathname()
在路径上,如果 urlparse()
结果的方案是 file
.
感谢@eryksun 的评论,指出 pip uses url2pathname()
. pip 还展示了如何更多地概括代码以处理 Windows UNC 路径,这些路径用于 Windows 共享网络文件夹等内容。如果方案是 'file'
,似乎可以检测到 UNC 路径并且 netloc 是非空的,我们需要在使用 UNC 路径之前添加几个反斜杠。
>>> parse_result = urllib.parse.urlparse('file://some-host/Shared Travel Photos/20170312_112803.jpg')
>>> parse_result
ParseResult(scheme='file', netloc='some-host', path='/Shared Travel Photos/20170312_112803.jpg', params='', query='', fragment='')
>>> urllib.request.url2pathname(r'\\' + parse_result.netloc + parse_result.path)
'\\\\some-host\\Shared Travel Photos\\20170312_112803.jpg'
关于python - Windows 文件方案 URI 上的 urlparse() 在开始时留下额外的斜杠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43911052/