上一篇咱們講解了Scrapy的工作機制和如何使用Scrapy爬取美女圖片,而今天接着講解Scrapy爬取美女圖片,不過采取了不同的方式和代碼實現,對Scrapy的功能進行更深入的運用。(我的新書《Python爬蟲開發與項目實戰》出版了,大家可以看一下樣章)
在學習Scrapy官方文檔的過程中,發現Scrapy自身實現了圖片和文件的下載功能,不需要咱們之前自己實現圖片的下載(不過原理都一樣)。
在官方文檔中,我們可以看到下面一些話:Scrapy為下載item中包含的文件(比如在爬取到產品時,同時也想保存對應的圖片)提供了一個可重用的 item pipelines . 這些pipeline有些共同的方法和結構(我們稱之為media pipeline)。一般來說你會使用Files Pipeline或者 Images Pipeline.
這兩種pipeline都實現了以下特性:
-
避免重新下載最近已經下載過的數據
-
Specifying where to store the media (filesystem directory, Amazon S3 bucket)
The Images Pipeline has a few extra functions for processing images:
-
將所有下載的圖片轉換成通用的格式(JPG)和模式(RGB)
-
縮略圖生成
-
檢測圖像的寬/高,確保它們滿足最小限制
這個管道也會為那些當前安排好要下載的圖片保留一個內部隊列,並將那些到達的包含相同圖片的項目連接到那個隊列中。 這可以避免多次下載幾個項目共享的同一個圖片。
從上面的話中,我們可以了解到 Scrapy不僅可以下載圖片,還可以生成指定大小的縮略圖,這就非常有用。
使用Files Pipeline
當使用 FilesPipeline
,典型的工作流程如下所示:
-
在一個爬蟲里,你抓取一個項目,把其中圖片的URL放入
file_urls
組內。 -
項目從爬蟲內返回,進入項目管道。
-
當項目進入
FilesPipeline
,file_urls
組內的URLs將被Scrapy的調度器和下載器(這意味着調度器和下載器的中間件可以復用)安排下載,當優先級更高,會在其他頁面被抓取前處理。項目會在這個特定的管道階段保持“locker”的狀態,直到完成文件的下載(或者由於某些原因未完成下載)。 -
當文件下載完后,另一個字段(
files
)將被更新到結構中。這個組將包含一個字典列表,其中包括下載文件的信息,比如下載路徑、源抓取地址(從file_urls
組獲得)和圖片的校驗碼(checksum)。files
列表中的文件順序將和源file_urls
組保持一致。如果某個圖片下載失敗,將會記錄下錯誤信息,圖片也不會出現在files
組中。
使用Images Pipeline
當使用Imagespipeline
,典型的工作流程如下所示:
-
在一個爬蟲里,你抓取一個項目,把其中圖片的URL放入
images_urls
組內。 -
項目從爬蟲內返回,進入項目管道。
-
當項目進入
Imagespipeline
,images_urls
組內的URLs將被Scrapy的調度器和下載器(這意味着調度器和下載器的中間件可以復用)安排下載,當優先級更高,會在其他頁面被抓取前處理。項目會在這個特定的管道階段保持“locker”的狀態,直到完成文件的下載(或者由於某些原因未完成下載)。 -
當文件下載完后,另一個字段(
images
)將被更新到結構中。這個組將包含一個字典列表,其中包括下載文件的信息,比如下載路徑、源抓取地址(從images_urls
組獲得)和圖片的校驗碼(checksum)。images
列表中的文件順序將和源images_urls
組保持一致。如果某個圖片下載失敗,將會記錄下錯誤信息,圖片也不會出現在images
組中。
Pillow 是用來生成縮略圖,並將圖片歸一化為JPEG/RGB格式,因此為了使用圖片管道,你需要安裝這個庫。 Python Imaging Library (PIL) 在大多數情況下是有效的,但眾所周知,在一些設置里會出現問題,因此我們推薦使用 Pillow 而不是PIL.
咱們這次用到的就是Images Pipeline,用來下載圖片,同時使用 Pillow 生成縮略圖。在安裝Scrapy的基礎上,使用pip install pillow 安裝這個模塊。
打開cmd,輸入scrapy startproject jiandan,這時候會生成一個工程,然后我把整個工程復制到pycharm中(還是使用IDE開發快)。
上圖就是工程的結構。
jiandanSpider.py ------Spider 蜘蛛
items.py -----------------對要爬取數據的模型定義
pipelines.py-------------咱們最終要存儲的數據
settings.py----------------對Scrapy的配置
接下來我把代碼貼一下(復制代碼請到我博客):
jiandanSpider.py(和之前沒有變化): #coding:utf-8 #需要安裝pillow模塊 import scrapy from jiandan.items import JiandanItem from scrapy.crawler import CrawlerProcess class jiandanSpider(scrapy.Spider): name = 'jiandan' allowed_domains = [] start_urls = ["http://jandan.net/ooxx"] def parse(self, response): item = JiandanItem() item['image_urls'] = response.xpath('//img//@src').extract()#提取圖片鏈接 # print 'image_urls',item['image_urls'] yield item new_url= response.xpath('//a[@class="previous-comment-page"]//@href').extract_first()#翻頁 # print 'new_url',new_url if new_url: yield scrapy.Request(new_url,callback=self.parse)
items.py(增加了一個字段,請看之前對Images Pipeline的描述) : # -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # http://doc.scrapy.org/en/latest/topics/items.html import scrapy class JiandanItem(scrapy.Item): # define the fields for your item here like: image_urls = scrapy.Field()#圖片的鏈接 images = scrapy.Field()
pipelines.py(改變最大,看注釋): # -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html import os import urllib import scrapy from scrapy.exceptions import DropItem from scrapy.pipelines.images import ImagesPipeline from jiandan import settings class JiandanPipeline(ImagesPipeline):#繼承ImagesPipeline這個類,實現這個功能 def get_media_requests(self, item, info):#重寫ImagesPipeline get_media_requests方法 ''' :param item: :param info: :return: 在工作流程中可以看到, 管道會得到文件的URL並從項目中下載。 為了這么做,你需要重寫 get_media_requests() 方法, 並對各個圖片URL返回一個Request: ''' for image_url in item['image_urls']: yield scrapy.Request(image_url) def item_completed(self, results, item, info): ''' :param results: :param item: :param info: :return: 當一個單獨項目中的所有圖片請求完成時(要么完成下載,要么因為某種原因下載失敗), item_completed() 方法將被調用。 ''' image_paths = [x['path'] for ok, x in results if ok] if not image_paths: raise DropItem("Item contains no images") return item
settings.py(主要是對縮略圖的設置): # -*- coding: utf-8 -*- # Scrapy settings for jiandan project # # For simplicity, this file contains only settings considered important or # commonly used. You can find more settings consulting the documentation: # # http://doc.scrapy.org/en/latest/topics/settings.html # http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html # http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html BOT_NAME = 'jiandan' SPIDER_MODULES = ['jiandan.spiders'] NEWSPIDER_MODULE = 'jiandan.spiders' ITEM_PIPELINES = { 'jiandan.pipelines.JiandanPipeline': 1, } # ITEM_PIPELINES = {'jiandan.pipelines.ImagesPipeline': 1} IMAGES_STORE='E:\\jiandan2' DOWNLOAD_DELAY = 0.25 IMAGES_THUMBS = {#縮略圖的尺寸,設置這個值就會產生縮略圖 'small': (50, 50), 'big': (200, 200), }
最后咱們開始運行程序,cmd切換到工程目錄,
輸入scrapy crawl jiandan,啟動爬蟲。。。
大約25分鍾左右,爬蟲工作結束。。。
咱們去看看美女圖吧。
咱們打開thumbs文件夾,看看縮略圖,下面有咱們設置的不同的尺寸。
今天的分享就到這里,如果大家覺得還可以呀,記得打賞呦。
歡迎大家支持我公眾號:
本文章屬於原創作品,歡迎大家轉載分享。尊重原創,轉載請注明來自:七夜的故事 http://www.cnblogs.com/qiyeboy/