下载图像并保存到本地文件系统
有时,在抓取时,我们只是下载并解析数据(例如 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 中存储文件。 通过这种类型的实现,通过接口继承,我们可以轻松地替换实现。