46

在 WeasyPrint 的公共 API 中,我接受 HTML 输入的文件名(以及其他类型)。任何与内置文件一起使用的文件名都open()应该有效,但我需要将其转换为file://方案中的 URL,稍后将传递给urllib.urlopen().

(内部的一切都是 URL 形式。我需要有一个文档的“基本 URL”,以便用 . 解析相对 URL 引用urlparse.urljoin()。)

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()

但是,根据文献,我不仅应该在前面加上……除非我不应该:在 Windows 上,结果已经以三个斜杠开头。file:file://nturl2path.pathname2url()

所以问题是:有没有更好的方法来做到这一点并使其跨平台?

4

4 回答 4

80

为了完整起见,在 Python 3.4+ 中,您应该这样做:

import pathlib

pathlib.Path(absolute_path_string).as_uri()
于 2015-08-09T15:43:25.767 回答
33

我不确定文档是否足够严格以保证它,但我认为这在实践中有效:

import urlparse, urllib

def path2url(path):
    return urlparse.urljoin(
      'file:', urllib.pathname2url(path))
于 2013-01-12T21:38:56.140 回答
5

归功于@danodonovan上面的评论。

对于 Python3,以下代码将起作用:

from urllib.parse import urljoin
from urllib.request import pathname2url

def path2url(path):
    return urljoin('file:', pathname2url(path))
于 2015-06-08T06:14:30.967 回答
0

以下内容对您有用吗?

from urlparse import urlparse, urlunparse

urlunparse(urlparse('yourURL')._replace(scheme='file'))
于 2012-07-27T12:48:41.593 回答