python scrapy 使用ImagePipeline下载图片

 

在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

被存储为:/full/3afec3b4765f8f0a07b78f98c07b83f013567a0a.jpg

(4) 避免重复抓取

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

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

(5) 图片压缩

IMAGES_THUMBS = {

’small’: (50, 50),

’big’: (270, 270),

}

压缩后存放在:/thumbs//.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(resultsitemsinfo):

所有图片处理完毕后(不管下载成功或失败),会调用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

 

通过在setting.py文件中通过给IMAGES_STORE赋值,就可以指定图片的保存路径。
并且默认情况下,文件名是通过对url使用SHA1 hash得来的。
现在我想以原来的图片名进行保存.

查看下ImagePipeline的源码,发现可以重写file_path函数以修改图片名称,例如:

def file_path(self, request, response=None, info=None):
    image_guid = request.url.split('/')[-1]
    file_name= image_guid.split('.')[0]+'.jpg'
    return 'full/%s' % (file_name)

这样保存的图片就是原图片名,但是thumbs里面的还是哈希名,这个可能要修改

def thumb_path(self, request, thumb_id, response=None, info=None):

函数才行

 

 

你可能感兴趣的:(Python学习)