scrapy的快速入門(二)

下載及處理文件和圖片
Scrapy為下載item中包含的文件(比如在爬取到產(chǎn)品時彤委,同時也想保存對應的圖片)提供了一個可重用的 item pipelines . 這些pipeline有些共同的方法和結構(我們稱之為media pipeline)豌汇。一般來說你會使用Files Pipeline或者 Images Pipeline相恃。
這兩種pipeline都實現(xiàn)了以下特性:
1、避免重新下載最近已經(jīng)下載過的數(shù)據(jù)陕赃;
2肛响、指定存儲媒體的位置(文件系統(tǒng)目錄闪檬,Amazon S3 bucket)圖像管道有一些額外的功能來處理圖像;
3氛悬、將所有下載的圖片轉換成通用的格式(JPG)和模式(RGB)则剃;
4、縮略圖生成如捅;
5棍现、檢測圖像的寬/高,確保它們滿足最小限制镜遣;

這個管道也會為那些當前安排好要下載的圖片保留一個內(nèi)部隊列轴咱,并將那些到達的包含相同圖片的項目連接到那個隊列中。 這可以避免多次下載幾個項目共享的同一個圖片烈涮。

一朴肺、使用Files Pipeline
當使用 FilesPipeline ,典型的工作流程如下所示:
1坚洽、在一個爬蟲里戈稿,你抓取一個項目,把其中圖片的URL放入 file_urls 組內(nèi)讶舰。
2鞍盗、項目從爬蟲內(nèi)返回,進入項目管道跳昼。
3般甲、當項目進入 FilesPipeline,file_urls 組內(nèi)的URLs將被Scrapy的調度器和下載器(這意味著調度器和下載器的中間件可以復用)安排下載鹅颊,當優(yōu)先級更高敷存,會在其他頁面被抓取前處理。項目會在這個特定的管道階段保持“l(fā)ocker”的狀態(tài)堪伍,直到完成文件的下載(或者由于某些原因未完成下載)锚烦。
4、當文件下載完后帝雇,另一個字段(files)將被更新到結構中涮俄。這個組將包含一個字典列表,其中包括下載文件的信息尸闸,比如下載路徑彻亲、源抓取地址(從 file_urls 組獲得)和圖片的校驗碼(checksum)孕锄。 files 列表中的文件順序將和源 file_urls 組保持一致。如果某個圖片下載失敗苞尝,將會記錄下錯誤信息硫惕,圖片也不會出現(xiàn)在 files 組中。

二野来、使用圖像管道Images Pipeline
當使用 ImagesPipeline 恼除,典型的工作流程如下所示:
1、在一個爬蟲里曼氛,你抓取一個項目豁辉,把其中圖片的URL放入 image_urls 組內(nèi)。
2舀患、項目從爬蟲內(nèi)返回徽级,進入項目管道。
3聊浅、當項目進入 ImagesPipeline餐抢,image_urls 組內(nèi)的URLs將被Scrapy的調度器和下載器(這意味著調度器和下載器的中間件可以復用)安排下載,當優(yōu)先級更高低匙,會在其他頁面被抓取前處理旷痕。項目會在這個特定的管道階段保持“l(fā)ocker”的狀態(tài),直到完成文件的下載(或者由于某些原因未完成下載)顽冶。
4欺抗、當文件下載完后,另一個字段(images)將被更新到結構中强重。這個組將包含一個字典列表绞呈,其中包括下載文件的信息,比如下載路徑间景、源抓取地址(從 image_urls 組獲得)和圖片的校驗碼(checksum)佃声。 files 列表中的文件順序將和源 image_urls 組保持一致。如果某個圖片下載失敗倘要,將會記錄下錯誤信息圾亏,圖片也不會出現(xiàn)在 images 組中。

使用ImagesPipeline非常類似于使用FilesPipeline碗誉,除了使用的默認字段名稱不同:您使用image_urls作為項目的圖像URL召嘶,并將填充圖像字段以獲取有關下載的圖像的信息。
使用ImagesPipeline進行圖像文件的優(yōu)點是您可以配置一些額外的功能哮缺,例如生成縮略圖,并根據(jù)大小對圖像進行過濾甲喝。
Pillow 是用來生成縮略圖尝苇,并將圖片歸一化為JPEG/RGB格式,因此為了使用圖片管道,你需要安裝這個庫糠溜。 Python Imaging Library (PIL) 在大多數(shù)情況下是有效的淳玩,但眾所周知,在一些設置里會出現(xiàn)問題非竿,因此我們推薦使用 Pillow 而不是PIL蜕着。

下面利用Images Pipeline爬取花瓣網(wǎng)下載想要的圖片。

1红柱、新建一個工程承匣,打開cmd,
輸入scrapy startproject huaban_imagepipeline

新建工程

這里的每個文件的含義上一篇文章scrapy的快速入門(一)已介紹過了锤悄,可以自行翻看之前的文章韧骗;
2、定制item

# -*- 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 HuabanImagepipelineItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    image_urls = scrapy.Field()  # 圖片的鏈接
    images = scrapy.Field()

3零聚、爬蟲的關鍵部分——spiders
在spiders的文件下新建一個huaban_spider.py

import scrapy
from ..items import HuabanImagepipelineItem
from scrapy.conf import settings #從settings文件中導入Cookie袍暴,這里也可以from scrapy.conf import settings.COOKIE
import requests
import json
import math
from scrapy.http import Request


class HuabanSpider(scrapy.Spider):
    name = "huabanSpider"
    allowed_domains = ['huaban.com']
    query = "張敏"
    start_urls = ['http://huaban.com/search/?q=%s' % query]
    # 帶著Cookie向網(wǎng)頁發(fā)請求
    cookie = settings['COOKIE']
    #利用抓包獲取必要的參數(shù),這里我用的是postman
    headers = {
        'cookies': 'uid=21839587; sid=8ckMdriGQD28yFUdISQIqykQwGn.KuxyNV3X2l9A87ShUPD1LLauT6PZdgi4AUm44wZqFXs;',
        'X-Requested-With': 'XMLHttpRequest',
    }

    html = requests.get(start_urls[0], headers = headers).content
    infos = json.loads(html)
    totalpage = math.ceil(int(infos['pin_count'])/20) #總的頁數(shù)

    #構造每頁的鏈接
    def parse(self, response):
        for i in range(1, int(self.totalpage) + 1):
            page = str(i)
            urls = ["http://huaban.com/search/?q={}&page={}".format(self.query, page)]
            for url in urls:
                yield Request(url, headers = self.headers, meta = {'key':url}, callback=self.parse_image)

    #構造每個圖片下載的鏈接
    def parse_image(self, response):
        item = HuabanImagepipelineItem()
        pin_html = requests.get(response.meta['key'], headers=self.headers).content
        infos = json.loads(pin_html)
        pins = infos['pins']
        url_list = []
        for pin in pins:
            key_id = pin['file']['key']
            download_url = "http://img.hb.aicdn.com/" + key_id + "_fw658"
            url_list.append(download_url)
        item['image_urls'] = url_list
        yield item

4隶症、圖片管道pipeline

# -*- 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
from scrapy.exceptions import DropItem
from scrapy.pipelines.images import ImagesPipeline
import scrapy


class HuabanImagepipelinePipeline(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):
        '''
        當一個單獨項目中的所有圖片請求完成時(要么完成下載,要么因為某種原因下載失斔塘)习蓬,
         item_completed() 方法將被調用。
        '''
        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

在自定義ImagePipeline代碼中措嵌,作為重要的是要重載get_media_requests(self, item, info)和item_completed(self, results, item, info)這兩個函數(shù)躲叼。
1)get_media_requests(self,item, info):
ImagePipeline根據(jù)image_urls中指定的url進行爬取,可以通過get_media_requests為每個url生成一個Request企巢;比如:

    def get_media_requests(self, item, info):
        for image_url in item['image_urls']:
            yield scrapy.Request(image_url)

2)圖片下載完畢后枫慷,處理結果會以二元組的方式返回給item_completed()函數(shù)。這個二元組定義如下:
(success, image_info_or_failure)
其中浪规,第一個元素表示圖片是否下載成功或听;第二個元素是一個字典。比如:

    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

5笋婿、在settings.py中設置條件和屬性

# -*- coding: utf-8 -*-
import random
from useragent import Agent  #導入請求頭誉裆,防止被ban
BOT_NAME = 'huabanSpider'

SPIDER_MODULES = ['huaban_imagepipeline.spiders']
NEWSPIDER_MODULE = 'huaban_imagepipeline.spiders'

ITEM_PIPELINES = {
    'huaban_imagepipeline.pipelines.HuabanImagepipelinePipeline': 1,
}


# Crawl responsibly by identifying yourself (and your website) on the user-agent


USER_AGENT = '%s'%random.choice(Agent.user_agent)
#USER_AGENT = 'huaban_imagepipeline (+http://www.yourdomain.com)'

# Obey robots.txt rules
ROBOTSTXT_OBEY = True

# Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS = 100

# Retry many times since proxies often fail
RETRY_TIMES = 10
# Retry on most error codes since proxies fail for different reasons
RETRY_HTTP_CODES = [500, 503, 504, 400, 403, 404, 408]

# Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.2
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16

# Disable cookies (enabled by default)禁止使用cookie
COOKIES_ENABLED = False
#圖片存儲路徑
IMAGES_STORE='E:\\spider\\pictures\\huaban\\zm'
#存儲縮略圖
IMAGES_THUMBS = {#縮略圖的尺寸,設置這個值就會產(chǎn)生縮略圖
    'small': (50, 50),
    'big': (200, 200),
}

運行結果:
會生成2個文件夾缸濒,

圖片

full:原圖足丢,
thumbs:縮略圖粱腻,包含2個文件夾:big、small斩跌,

縮略圖
Paste_Image.png
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绍些,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子耀鸦,更是在濱河造成了極大的恐慌柬批,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,332評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件袖订,死亡現(xiàn)場離奇詭異氮帐,居然都是意外死亡,警方通過查閱死者的電腦和手機著角,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評論 3 385
  • 文/潘曉璐 我一進店門揪漩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吏口,你說我怎么就攤上這事奄容。” “怎么了产徊?”我有些...
    開封第一講書人閱讀 157,812評論 0 348
  • 文/不壞的土叔 我叫張陵昂勒,是天一觀的道長。 經(jīng)常有香客問我舟铜,道長戈盈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,607評論 1 284
  • 正文 為了忘掉前任谆刨,我火速辦了婚禮塘娶,結果婚禮上,老公的妹妹穿的比我還像新娘痊夭。我一直安慰自己刁岸,他們只是感情好,可當我...
    茶點故事閱讀 65,728評論 6 386
  • 文/花漫 我一把揭開白布她我。 她就那樣靜靜地躺著虹曙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪番舆。 梳的紋絲不亂的頭發(fā)上酝碳,一...
    開封第一講書人閱讀 49,919評論 1 290
  • 那天,我揣著相機與錄音恨狈,去河邊找鬼疏哗。 笑死,一個胖子當著我的面吹牛拴事,可吹牛的內(nèi)容都是我干的沃斤。 我是一名探鬼主播圣蝎,決...
    沈念sama閱讀 39,071評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼刃宵,長吁一口氣:“原來是場噩夢啊……” “哼衡瓶!你這毒婦竟也來了?” 一聲冷哼從身側響起牲证,我...
    開封第一講書人閱讀 37,802評論 0 268
  • 序言:老撾萬榮一對情侶失蹤哮针,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后坦袍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體十厢,經(jīng)...
    沈念sama閱讀 44,256評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,576評論 2 327
  • 正文 我和宋清朗相戀三年捂齐,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛮放。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,712評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡奠宜,死狀恐怖包颁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情压真,我是刑警寧澤娩嚼,帶...
    沈念sama閱讀 34,389評論 4 332
  • 正文 年R本政府宣布,位于F島的核電站滴肿,受9級特大地震影響岳悟,放射性物質發(fā)生泄漏。R本人自食惡果不足惜泼差,卻給世界環(huán)境...
    茶點故事閱讀 40,032評論 3 316
  • 文/蒙蒙 一贵少、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧堆缘,春花似錦滔灶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至潜沦,卻和暖如春萄涯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背唆鸡。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評論 1 266
  • 我被黑心中介騙來泰國打工涝影, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人争占。 一個月前我還...
    沈念sama閱讀 46,473評論 2 360
  • 正文 我出身青樓燃逻,卻偏偏與公主長得像序目,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子伯襟,可洞房花燭夜當晚...
    茶點故事閱讀 43,606評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,834評論 25 707
  • Media Pipeline Scrapy為下載item中包含的文件(比如在爬取到產(chǎn)品時猿涨,同時也想保存對應的圖片)...
    cnkai閱讀 2,446評論 2 1
  • scrapy學習筆記(有示例版) 我的博客 scrapy學習筆記1.使用scrapy1.1創(chuàng)建工程1.2創(chuàng)建爬蟲模...
    陳思煜閱讀 12,670評論 4 46
  • 上一篇咱們講解了Scrapy的工作機制和如何使用Scrapy爬取美女圖片,而今天接著講解Scrapy爬取美女圖片姆怪,...
    qiye閱讀 4,904評論 9 18
  • 又回到達州了叛赚,走在熟悉的街道,回想到爸爸稽揭,想到以前的時光俺附,感覺爸爸的臉還在面前,難受
    葉增援閱讀 61評論 0 0