下载和处理文件和图像
Scrapy提供可重复使用的项目管道,用于下载附加到特定项目上的文件(例如,当您刮擦产品并且还想在本地下载其图像时)。这些管道共享一些功能和结构(我们将其称为媒体管道),但通常您将使用文件管道或图像管道。
两个管道都实现了这些功能:
避免重新下载最近下载的媒体
指定存储媒体的位置(文件系统目录,Amazon S3 bucket)
图像管道有一些额外的功能来处理图像:
将所有下载的图像转换为通用格式(JPG)和模式(RGB)
缩略图生成
检查图像宽度/高度,以确保它们符合最小限制
管道还保留当前正在安排下载的那些媒体URL的内部队列,并将包含相同媒体的到达的响应连接到该队列。这避免了由多个项目共享时多次下载相同的媒体。
使用文件管道
使用FilesPipeline时的典型工作流程如下所示:
在Spider中,您可以将项目拖放到file_urls字段中。
项目从蜘蛛返回并转到物料管道。
当项目到达FilesPipeline时,使用标准Scrapy调度程序和下载器(这意味着调度程序和下载程序中间件被重新使用),file_urls字段中的URL被安排下载,但是具有更高的优先级,在其他页面被刮除之前进行处理。该项目在该特定流水线阶段保持“锁定”,直到文件完成下载(或由于某种原因失败)。
当文件下载时,将使用结果填充另一个字段(文件)。该字段将包含具有关于下载文件的信息的例子,例如下载的路径,原始的被删除的URL(取自file_urls字段)和文件校验和。文件列表中的文件字段将保留与原始file_urls字段相同的顺序。如果某些文件下载失败,将会记录一个错误,该文件将不会显示在文件字段中。
使用图像管道
使用ImagesPipeline非常类似于使用FilesPipeline,除了使用的默认字段名称不同:您使用image_urls作为项目的图像URL,并将填充图像字段以获取有关下载的图像的信息。
使用ImagesPipeline进行图像文件的优点是您可以配置一些额外的功能,如生成缩略图,并根据大小对图像进行过滤。
图像管道使用枕头缩略图并将图像归一化为JPEG / RGB格式,因此您需要安装此库才能使用。 Python图像库(PIL)也可以在大多数情况下起作用,但是在某些设置中会引起麻烦,所以我们建议使用Pillow而不是PIL。
启用媒体管道
要启用媒体管道,您必须先将其添加到项目ITEM_PIPELINES设置中。
对于图像管道,使用:
ITEM_PIPELINES = {'scrapy.pipelines.images.ImagesPipeline':1}
对于文件管道,请使用:
ITEM_PIPELINES = {'scrapy.pipelines.files.FilesPipeline':1}
注意
您也可以同时使用文件和图像管道。
然后,将目标存储设置配置为将用于存储下载的映像的有效值。否则管道将保持禁用,即使将其包含在ITEM_PIPELINES设置中。
对于文件管道,设置FILES_STORE设置:
FILES_STORE ='/ path / to / valid / dir'
对于图像流水线,设置IMAGES_STORE设置:
IMAGES_STORE ='/ path / to / valid / dir'
支持的存储
文件系统目前是唯一正式支持的存储,但也支持在Amazon S3中存储文件。
文件系统存储
这些文件使用其文件名的URL的SHA1哈希存储。
例如,以下图像URL:
http://www.example.com/image.jpg
谁的SHA1哈希是:
3afec3b4765f8f0a07b78f98c07b83f013567a0a
将下载并存储在以下文件中:
<IMAGES_STORE> /full/3afec3b4765f8f0a07b78f98c07b83f013567a0a.jpg
哪里:
<IMAGES_STORE>是图像管道的IMAGES_STORE设置中定义的目录。
full是一个子目录,用于将完整图像与缩略图分离(如果使用)。有关详细信息,请参阅图像的缩略图生成。
亚马逊S3存储
FILES_STORE和IMAGES_STORE可以代表Amazon S3存储区。 Scrapy将自动将文件上传到存储桶。
例如,这是一个有效的IMAGES_STORE值:
IMAGES_STORE ='s3:// bucket / images'
您可以修改由FILES_STORE_S3_ACL和IMAGES_STORE_S3_ACL设置定义的存储文件的访问控制列表(ACL)策略。缺省情况下,ACL设置为private。要使文件公开可用,请使用公共阅读策略:
IMAGES_STORE_S3_ACL ='public-read'
有关更多信息,请参阅“亚马逊S3开发人员指南”中的固定ACL。
用法示例
为了首先使用媒体流水线,启用它。
然后,如果蜘蛛用URL键(file_urls或image_urls,分别用于文件或图像管道)返回dict,则管道将把结果放在相应的键(文件或图像)下。
如果您更喜欢使用Item,那么请定义具有必要字段的自定义项目,例如Image Pipeline的示例:
进口刮板
MyItem类(scrapy.Item):
#...其他项目字段...
image\_urls = scrapy.Field()
图像= scrapy.Field()
如果要为URL键或结果键使用其他字段名称,也可以覆盖它。
对于文件管道,设置FILES_URLS_FIELD和/或FILES_RESULT_FIELD设置:
FILES_URLS_FIELD ='field_name_for_your_files_urls'
FILES_RESULT_FIELD ='field_name_for_your_processed_files'
对于图像流水线,设置IMAGES_URLS_FIELD和/或IMAGES_RESULT_FIELD设置:
IMAGES_URLS_FIELD ='field_name_for_your_images_urls'
IMAGES_RESULT_FIELD ='field_name_for_your_processed_images'
如果您需要更复杂的内容,并希望覆盖自定义管道行为,请参阅扩展介质管道。
如果您有多个图像流水线继承自ImagePipeline,并且您希望在不同管道中具有不同的设置,您可以将设置键设置为以流水线类的大写名称。例如。如果您的管道称为MyPipeline,并且您想要自定义IMAGES_URLS_FIELD,则可以定义设置MYPIPELINE_IMAGES_URLS_FIELD,并使用您的自定义设置。
附加功能
文件过期
图像管道避免下载最近下载的文件。要调整此保留延迟,请使用FILES_EXPIRES设置(或IMAGES_EXPIRES,在图像管道的情况下),其指定天数延迟:
#120天延迟文件到期
FILES_EXPIRES = 120
#30天延迟图像过期
IMAGES_EXPIRES = 30
两种设置的默认值为90天。
如果您有管道分类FilesPipeline并且您想要有不同的设置,您可以设置以大写类名称前面的设置键。例如。给定管道类叫MyPipeline可以设置设置键:
MYPIPELINE_FILES_EXPIRES = 180
流水线MyPipeline将有到期时间设置为180。
图像缩略图生成
图像管道可以自动创建下载图像的缩略图。
为了使用此功能,您必须将IMAGES_THUMBS设置为字典,其中键是缩略图名称,值是其尺寸。
例如:
IMAGES_THUMBS = {
“小”:(50,50),
“大”:(270,270),
}
使用此功能时,图像流水线将使用以下格式创建每个指定大小的缩略图:
<IMAGES_STORE> /拇指/ <size_name> / <image_id> .JPG
哪里:
<size_name>是IMAGES_THUMBS字典键中指定的(小,大等)
<image_id>是图像网址的SHA1哈希
使用小而大的缩略图名称存储的图像文件示例:
<IMAGES_STORE> /full/63bbfea82b8880ed33cdb762aa11fab722a90a24.jpg
<IMAGES_STORE> /thumbs/small/63bbfea82b8880ed33cdb762aa11fab722a90a24.jpg
<IMAGES_STORE> /thumbs/big/63bbfea82b8880ed33cdb762aa11fab722a90a24.jpg
第一个是从网站下载的完整图像。
过滤小图像
使用图像流水线时,可以通过在IMAGES_MIN_HEIGHT和IMAGES_MIN_WIDTH设置中指定最小允许尺寸来放弃太小的图像。
例如:
IMAGES_MIN_HEIGHT = 110
IMAGES_MIN_WIDTH = 110
注意
大小限制根本不影响缩略图生成。
可以设置一个大小约束或两者。当设置它们时,仅保存满足两个最小尺寸的图像。对于上述示例,尺寸(105×105)或(105×200)或(200×105)的图像将全部被丢弃,因为至少一个维度比约束短。
默认情况下,没有大小限制,因此所有图像都被处理。
允许重定向
默认情况下,媒体流水线忽略重定向,即对媒体文件URL请求的HTTP重定向将意味着媒体下载被认为是失败的。
要处理媒体重定向,请将此设置设置为True:
MEDIA_ALLOW_REDIRECTS = True
扩展媒体管道
请参阅这里您可以在自定义文件管道中覆盖的方法:
类scrapy.pipelines.files.FilesPipeline
get_media_requests(item,info)
如工作流程所示,流水线将从该项目中获取要下载的图像的URL。为此,您可以覆盖get_media_requests()方法并返回每个文件URL的请求:
def get_media_requests(self,item,info):
对于\['file\_urls'\]中的file\_url:
产生scrapy.Request(file\_url)
这些请求将由管道处理,当它们完成下载时,结果将被发送到item_completed()方法,作为2元素元组的列表。每个元组将包含(success,file_info_or_error),其中:
success是一个布尔值,如果图像成功下载,则为True,如果由于某种原因失败,则为False
file_info_or_error是一个包含以下键(如果成功为True)或如果出现问题则为Twisted Failure的dict。
url - 从下载文件的网址。这是从get_media_requests()方法返回的请求的URL。
路径 - 存储文件的路径(相对于FILES_STORE)
校验和 - 图像内容的MD5哈希值
由item_completed()接收的元组的列表保证保留从get_media_requests()方法返回的请求的相同顺序。
以下是结果参数的典型值:
[(真正,
{'checksum':'2b00042f7481c7b056c4b410d28f33cf',
'path':'full / 0a79c461a4062ac383dc4fade7bc09f1384a3910.jpg'
'url':'http://www.example.com/files/product1.pdf'}),
(假,
失败(...))]
默认情况下,get_media_requests()方法返回None,这意味着没有要下载的文件。
item_completed(结果,项目,信息)
当单个项目的所有文件请求已完成(完成下载或由于某些原因失败)时调用FilesPipeline.item_completed()方法。
item_completed()方法必须返回将发送到后续项目流水线阶段的输出,因此您必须返回(或删除)该项目,就像在任何管道中一样。
这里是一个item_completed()方法的例子,我们将文件路径(传递给结果)存储在file_paths项目字段中,如果不包含任何文件,我们删除该项目:
从scrapy.exceptions导入DropItem
def item_completed(self,results,item,info):
file\_paths = \[x \['path'\] for ok,x in results if ok\]
如果不是file\_paths:
提起DropItem(“Item contains no files”)
item \['file\_paths'\] = file\_paths
归还物品
默认情况下,item_completed()方法返回该项。
请参阅这里您可以在自定义图像流水线中覆盖的方法:
class scrapy.pipelines.images.ImagesPipeline
ImagesPipeline是FilesPipeline的扩展,定制字段名称并添加图像的自定义行为。
get_media_requests(item,info)
与FilesPipeline.get_media_requests()方法的工作方式相同,但对图像url使用不同的字段名称。
必须返回每个图片网址的请求。
item_completed(结果,项目,信息)
当单个项目的所有图像请求已完成(完成下载或由于某些原因失败)时,将调用ImagesPipeline.item_completed()方法。
与FilesPipeline.item_completed()方法相同,但使用不同的字段名称来存储图像下载结果。
默认情况下,item_completed()方法返回该项。
自定义图像流水线示例
以下是图像管道的完整示例,其方法示例如下: