将文件名转换为 file:// URL
Posted
技术标签:
【中文标题】将文件名转换为 file:// URL【英文标题】:Convert a filename to a file:// URL 【发布时间】:2012-07-26 02:42:26 【问题描述】:在 WeasyPrint 的公共 API 中,我接受 html 输入的文件名(以及其他类型)。任何与内置 open()
一起使用的文件名都应该可以使用,但我需要将其转换为 file://
方案中的 URL,稍后将传递给 urllib.urlopen()
。
(内部的一切都是 URL 形式。我需要有一个文档的“基本 URL”,以便使用 urlparse.urljoin()
解析相对 URL 引用。)
urllib.pathname2url 是一个开始:
将路径名路径从路径的本地语法转换为 URL 的路径组件中使用的形式。 这不会产生完整的 URL。返回值已经使用 quote() 函数引用。
重点是我的,但我确实需要一个完整的 URL。到目前为止,这似乎有效:
def path2url(path):
"""Return file:// URL from a filename."""
path = os.path.abspath(path)
if isinstance(path, unicode):
path = path.encode('utf8')
return 'file:' + urlparse.pathname2url(path)
RFC 3987 (IRI) 似乎推荐使用 UTF-8。但在这种情况下(URL 最终是用于 urllib)也许我应该使用sys.getfilesystemencoding()?
但是,基于the literature,我应该不只是在file:
前面加上file://
...除非我不应该:在Windows 上,nturl2path.pathname2url()
的结果已经以三个斜杠开头。
所以问题是:有没有更好的方法来做到这一点并使其跨平台?
【问题讨论】:
您不能只检查url[0:2] == '///'
之类的内容,如果为假,则添加两个额外的斜线吗?
约阿希姆,也许这行得通。我只是不知道要遵循什么规则来避免令人惊讶的极端情况。
嘿,您的示例代码使用了urlparse.pathname2url
,它不存在。你的意思是urllib.pathname2url
?
【参考方案1】:
感谢上述@danodonovan
的评论。
对于 Python3,以下代码将起作用:
from urllib.parse import urljoin
from urllib.request import pathname2url
def path2url(path):
return urljoin('file:', pathname2url(path))
【讨论】:
【参考方案2】:为了完整起见,在 Python 3.4+ 中,您应该这样做:
import pathlib
pathlib.Path(absolute_path_string).as_uri()
【讨论】:
这个模块也在 PyPI 上(对于其他 Python 版本)pypi.python.org/pypi/pathlib pathlib2 现在应该用于其他 Python 版本as_uri()
不适用于相对文件名(存在仅将部分文件名转换为(部分)URL 的用例【参考方案3】:
我不确定文档是否足够严格以保证这一点,但我认为这在实践中有效:
import urlparse, urllib
def path2url(path):
return urlparse.urljoin(
'file:', urllib.pathname2url(path))
【讨论】:
在 Linux、Windows 和 OS X 上测试过,并且在这三者上都可以正常工作。 而在 py3k 中,这变成了import urlib.parse as urlparse
和 import urlib.request as urllib
您应该在这里致电os.path.abspath(path)
。
如果您使用 six 库来确保 Python 2 和 3 的可移植性:return six.moves.urllib_parse.urljoin( "file://", six.moves.urllib.request.pathname2url(path))
这会产生看起来像file:///C:/foo%20bar/spam/eggs"
的url 不应该是file:///C%3A/foo%20bar/spam/eggs"
,冒号变成%3A
?【参考方案4】:
以下内容对您有用吗?
from urlparse import urlparse, urlunparse
urlunparse(urlparse('yourURL')._replace(scheme='file'))
【讨论】:
这个想法很有趣,但我不知道这是否足够。特别是,` in Windows filenames is supposed to become
/. Still on Windows, The C in
C:\foo\bar.html` 被解析为一个方案,然后被替换。预期输出为file:///C:/foo/bar.html
。以上是关于将文件名转换为 file:// URL的主要内容,如果未能解决你的问题,请参考以下文章