Scrapy ImagePipeline(圖片下載組件)

Scrapy用ImagesPipeline類提供一種方便的方式來下載和存儲圖片。須要PIL庫支持。html

主要特徵

  • 將下載圖片轉換成通用的JPG和RGB格式
  • 避免重複下載
  • 縮略圖生成
  • 圖片大小過濾

工做流程

  • 爬取一個Item,將圖片的URLs放入image_urls字段
  • Spider返回的Item,傳遞到Item Pipeline
  • Item傳遞到ImagePipeline,將調用Scrapy 調度器和下載器完成image_urls中的url的調度和下載。ImagePipeline會自動高優先級抓取這些url,於此同時,item會被鎖定直到圖片抓取完畢才被解鎖。
  • 圖片下載成功結束後,圖片下載路徑、url和校驗和等信息會被填充到images字段中。

定義Item

使用ImagePipeline須要在配置文件中配置ITEMPIPELINES屬性,並定義一個Item包含imageurls和images字段python

class ImageItem(Item):
    image_urls = Field()
    images = Field()
    image_paths = Field()

設置條件和屬性settings.py

ITEM_PIPELINES = ['demo.pipelines.MyImagesPipeline']  # ImagePipeline的自定義實現類
IMAGES_STORE = 'D:\\dev\\python\\scrapy\\demo\\img'   # 圖片存儲路徑
IMAGES_EXPIRES = 90                                   # 過時天數
IMAGES_MIN_HEIGHT = 100                               # 圖片的最小高度
IMAGES_MIN_WIDTH = 100                                # 圖片的最小寬度
# 圖片的尺寸小於IMAGES_MIN_WIDTH*IMAGES_MIN_HEIGHT的圖片都會被過濾

ImageSpider

from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector

from demo.items import ImageItem

class MyImageSpider(BaseSpider):
    name = "image_spider"
    allowed_domains = ["http://topit.me/"]
    start_urls = [
        "http://topit.me/",
    ]

    def parse(self, response):
        hxs = HtmlXPathSelector(response)
        imgs = hxs.select('//img/@src').extract()
        item = ImageItem()
        item['image_urls']=imgs
        return item

ImagePipeline

須要在自定義的ImagePipeline類中重載的方法:get_media_requests(item, info)item_completed(results, items, info)dom

正如工做流程所示,Pipeline將從item中獲取圖片的URLs並下載它們,因此必須重載get_media_requests,並返回一個Request對象,這些請求對象將被Pipeline處理,當完成下載後,結果將發送到item_completed方法,這些結果爲一個二元組的list,每一個元祖的包含(success, image_info_or_failure)。 * successboolean值,true表示成功下載 * image_info_or_error:若是success=trueimage_info_or_error詞典包含如下鍵值對* url:原始URL * path:本地存儲路徑 * checksum:校驗碼。失敗則包含一些出錯信息。scrapy

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

運行結果

$ scrapy crawl image_spider
.....
2013-09-10 15:49:48+0800 [image_spider] DEBUG: Scraped from <200 http://topit.me/>
    {'image_paths': ['full/4285ec809413767e8dd5daf4a57fbfe97d964e2e.jpg',
                     'full/b8088f68ba1d569c96b04a3664e115d4833544be.jpg',
                     ....
                     'full/97f2272a06191cda15abda57e03ec29eb5c51959.jpg',
                     'full/9afc3ed6b6cf8259b4065a0d2d79f49b6670c51b.jpg'],
     'image_urls': [u'http://img.topit.me/logo.gif',
                    u'http://fe.topit.me/e/a3/43/117387157785b43a3em.jpg',
                    ...
                    u'http://i.topit.me/9/v/3LOGi2v9m.jpg',
                    u'http://www.topit.me/img/link/mobile.jpg']}
2013-09-10 15:49:48+0800 [image_spider] INFO: Closing spider (finished)
....

注: 在這裏提醒一下,當使用多個pipeline組件時,經過setting-》ITEM-PIPELINE中的數值設置組建的運行順序,可是若是兩個pipeline的順序不一致,則只經過最開始的pipeline的item處理ide

但願你們多多指正,謝謝!url

相關文章
相關標籤/搜索