使用 urllib 解析 URL 来获取文件名

当从 URL 下载内容时,我们经常希望将其保存在文件中。 通常,将文件保存在一个名称在 URL 中的文件中就足够了。 但是URL是由很多片段组成的,那么我们如何从URL中找到实际的文件名,尤其是文件名后面经常有很多参数呢?

准备工作

我们将再次使用 URLUtility 类来完成此任务。该配方的代码文件是 04/02_parse_url.py。

怎么做

使用 python 解释器执行配方文件。 它将运行以下代码:

util = URLUtility(const.ApodEclipseImage())
print(util.filename_without_ext)

这会产生以下输出:

Reading URL: https://apod.nasa.gov/apod/image/1709/BT5643s.jpg
Read 171014 bytes
The filename is: BT5643s

工作原理

在 URLUtility 的构造函数中,调用了 urlib.parse.urlparse。下面演示了该函数的交互使用:

>>> parsed = urlparse(const.ApodEclipseImage())
>>> parsed
ParseResult(scheme='https', netloc='apod.nasa.gov',
path='/apod/image/1709/BT5643s.jpg', params='', query='', fragment='')

ParseResult 对象包含 URL 的各个组成部分。 路径元素包含路径和文件名。 对 .filename_without_ext 属性的调用仅返回不带扩展名的文件名:

@property
def filename_without_ext(self):
    filename = os.path.splitext(os.path.basename(self._parsed.path))[0]
    return filename

对 os.path.basename 的调用仅返回路径的文件名部分(包括扩展名)。 然后 os.path.splittext() 分隔文件名和扩展名,并且该函数返回该元组/列表的第一个元素(文件名)。

还有更多

这似乎很奇怪,这并没有将扩展名作为文件名的一部分返回。 这是因为我们不能假设我们收到的内容实际上与扩展中的隐含类型匹配。 使用 Web 服务器返回的标头来确定这一点更为准确。 这是我们的下一个示例。