现在的位置: 首页 > 综合 > 正文

Scrapy:ImagePipeline的使用

2013年06月09日 ⁄ 综合 ⁄ 共 2404字 ⁄ 字号 评论关闭

在scrapy中,为了爬取图片,可以将要爬取的图片的url放在image_urls字段中,在item从spider返回时,ImagePipeline会自动高优先级抓取这些url,于此同时,item会被锁定直到图片抓取完毕才被解锁。图片下载成功结束后,图片下载路径、url等信息会被填充到images字段中。

要想图片被成功抓取,需要做以下操作:

(1) 在items.py中添加image_urls和images字段,代码如下:

image_urls = Field()

images = Field()

(2) Enable ImagePipeline,在segttings.py中添加以下代码:

ITEM_PIPELINES = [’scrapy.contrib.pipeline.images.ImagesPipeline’]

IMAGES_STORE = ’/path/to/valid/dir’ #设置图片下载路径

(3) 图片存储

图片会根据原始url计算SHA1 hash值后进行存储;

如url:http://www.example.com/image.jpg

SHA1 哈希值为:3afec3b4765f8f0a07b78f98c07b83f013567a0a

被存储为:<IMAGES_STORE>/full/3afec3b4765f8f0a07b78f98c07b83f013567a0a.jpg

(4) 避免重复抓取

近期抓取过的图片不会再重抓,可以在settings.py中设置多少天内抓过的不被重抓。

IMAGES_EXPIRES = 90 #90天内抓取的都不会被重抓

(5) 图片压缩

IMAGES_THUMBS = {

’small’: (50, 50),

’big’: (270, 270),

}

压缩后存放在:<IMAGES_STORE>/thumbs/<size_name>/<image_id>.jpg

(6) 图片过滤

可以设置过滤下图片,设置方法如下:

IMAGES_MIN_HEIGHT = 110

IMAGES_MIN_WIDTH = 110

(7) 自定义ImagePipeline

可重载的函数:

get_media_requests(item, info):

ImagePipeline根据image_urls中指定的url进行爬取,可以通过get_media_requests为每个url生成一个Request。如:

def get_media_requests(self, item, info):

for image_url in item[’image_urls’]:

yield Request(image_url)

图片下载完毕后,处理结果会以二元组的方式返回给item_completed()函数。这个二元组定义如下:

(success, image_info_or_failure)

其中,第一个元素表示图片是否下载成功;第二个元素是一个字典,含义如下:

-url:图片url

-path:图片存储地址,跟IMAGE_STORE相关

-checksum:图片内容hash

get_media_requests函数返回示例如下:

[(True,

{’checksum’: ’2b00042f7481c7b056c4b410d28f33cf’,

’path’: ’full/7d97e98f8af710c7e7fe703abc8f639e0ee507c4.jpg’,

’url’: ’http://www.example.com/images/product1.jpg’}),

(True,

{’checksum’: ’b9628c4ab9b595f72f280b90c4fd093d’,

’path’: ’full/1ca5879492b8fd606df1964ea3c1e2f4520f076f.jpg’,

’url’: ’http://www.example.com/images/product2.jpg’}),

(False,

Failure(...))]

item_completed(results, items, info):

所有图片处理完毕后(不管下载成功或失败),会调用item_completed进行处理;示例程序如下:(默认情况下,item_completed会返回全部items

from scrapy.exceptions import DropItem

def item_completed(self, results, item, info):

image_paths = [x[’path’] for ok, x in results if ok]

if not image_paths:

raise DropItem("Item contains no images")

item[’image_paths’] = image_paths

return item

(8) 自定义ImagePipeline示例:

from scrapy.contrib.pipeline.images import ImagesPipeline

from scrapy.exceptions import DropItem

from scrapy.http import Request

class MyImagesPipeline(ImagesPipeline):

def get_media_requests(self, item, info):

for image_url in item[’image_urls’]:

yield Request(image_url)

def item_completed(self, results, item, info):

image_paths = [x[’path’] for ok, x in results if ok]

if not image_paths:

raise DropItem("Item contains no images")

item[’image_paths’] = image_paths

return item

抱歉!评论已关闭.