Scrapy爬取美女圖片續集 (原創)


  上一篇咱們講解了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 ,典型的工作流程如下所示:

  1. 在一個爬蟲里,你抓取一個項目,把其中圖片的URL放入 file_urls 組內。

  2. 項目從爬蟲內返回,進入項目管道。

  3. 當項目進入 FilesPipelinefile_urls 組內的URLs將被Scrapy的調度器和下載器(這意味着調度器和下載器的中間件可以復用)安排下載,當優先級更高,會在其他頁面被抓取前處理。項目會在這個特定的管道階段保持“locker”的狀態,直到完成文件的下載(或者由於某些原因未完成下載)。

  4. 當文件下載完后,另一個字段(files)將被更新到結構中。這個組將包含一個字典列表,其中包括下載文件的信息,比如下載路徑、源抓取地址(從 file_urls 組獲得)和圖片的校驗碼(checksum)。 files 列表中的文件順序將和源 file_urls 組保持一致。如果某個圖片下載失敗,將會記錄下錯誤信息,圖片也不會出現在 files 組中。

 

 

使用Images Pipeline

當使用Imagespipeline ,典型的工作流程如下所示:

  1. 在一個爬蟲里,你抓取一個項目,把其中圖片的URL放入 images_urls 組內。

  2. 項目從爬蟲內返回,進入項目管道。

  3. 當項目進入 Imagespipelineimages_urls 組內的URLs將被Scrapy的調度器和下載器(這意味着調度器和下載器的中間件可以復用)安排下載,當優先級更高,會在其他頁面被抓取前處理。項目會在這個特定的管道階段保持“locker”的狀態,直到完成文件的下載(或者由於某些原因未完成下載)。

  4. 當文件下載完后,另一個字段(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/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM