下载图像并保存到本地文件系统

有时,在抓取时,我们只是下载并解析数据(例如 HTML)以提取一些数据,然后丢弃我们读取的内容。 其他时候,我们希望通过将下载的内容存储为文件来保留它。

怎么做

此配方的代码示例位于 04/05_save_image_as_file.py 文件中。 文件中重要的部分是:

# download the image
item = URLUtility(const.ApodEclipseImage())

# create a file writer to write the data
FileBlobWriter(expanduser("~")).write(item.filename, item.data)

使用 Python 解释器运行该脚本,您将得到以下输出:

Reading URL: https://apod.nasa.gov/apod/image/1709/BT5643s.jpg
Read 171014 bytes
Attempting to write 171014 bytes to BT5643s.jpg:
The write was successful

工作原理

该示例只是使用标准 Python 文件访问函数将数据写入文件。 它通过使用用于写入数据的标准接口以及 FileBlobWriter 类中基于文件的实现,以面向对象的方式完成此操作:

""" Implements the IBlobWriter interface to write the blob to a file """
from interface import implements
from core.i_blob_writer import IBlobWriter

class FileBlobWriter(implements(IBlobWriter)):
    def __init__(self, location):
        self._location = location

    def write(self, filename, contents):
        full_filename = self._location + "/" + filename
        print ("Attempting to write {0} bytes to {1}:".format(len(contents), filename))
        with open(full_filename, 'wb') as outfile:
            outfile.write(contents)

        print("The write was successful")

向该类传递一个表示文件应放置的目录的字符串。 数据实际上是在稍后调用 .write() 方法期间写入的。 此方法合并文件名和目录(_location),然后打开/创建文件并写入字节。 with 语句确保文件已关闭。

还有更多

这种写入可以简单地使用包装代码的函数来处理。 该对象将在本章中重复使用。 我们可以使用 python 的鸭子类型,或者只是一个函数,但接口的清晰度更容易。 说到这里,下面是这个接口的定义:

""" Defines the interface for writing a blob of data to storage """
from interface import Interface

class IBlobWriter(Interface):
    def write(self, filename, contents):
        pass

我们还将看到该接口的另一个实现,它允许我们在 S3 中存储文件。 通过这种类型的实现,通过接口继承,我们可以轻松地替换实现。