Python爬蟲 --- 2.5 Scrapy之汽車之家爬蟲實踐

目的

Scrapy框架為文件和圖片的下載專門提供了兩個Item Pipeline 它們分別是:

FilePipeline

ImagesPipeline

這里主要介紹ImagesPipeline!!

目標(biāo)分析:

這次我們要爬的是 汽車之家:car.autohome.com.cn

最近喜歡吉利博越,所以看了不少這款車的資料。。。。

我們就點開博越汽車的圖片網(wǎng)站:

https://car.autohome.com.cn/pic/series/3788.html

傳統(tǒng)的Scrapy框架圖片下載

Scrapy 框架的實施:

  1. 創(chuàng)建scrapy項目和爬蟲:

    $ scrapy startproject Geely
    $ cd Geely
    $ scrapy genspider BoYue car.autohome.com.cn
    
  2. 編寫items.py:

    import scrapy
    
    class GeelyItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        
        # 存儲圖片分類
        catagory = scrapy.Field()
        
        # 存儲圖片地址
        image_urls = scrapy.Field()
        
        # ImagesPipeline 
        images = scrapy.Field()
    
  3. 編寫Spider:

    獲取高清圖片:

    通過分析縮略圖和高清圖的url,我們發(fā)現(xiàn)縮略圖只是多了t_罷了

    縮略圖地址:

    https://car3.autoimg.cn/cardfs/product/g25/M09/B0/61/t_autohomecar__wKgHIlpxMgyAWYh2AAaCZ2odx24585.jpg

    高清圖地址:

    https://car3.autoimg.cn/cardfs/product/g25/M09/B0/61/autohomecar__wKgHIlpxMgyAWYh2AAaCZ2odx24585.jpg

    # -*- coding: utf-8 -*-
    import scrapy
    
    #導(dǎo)入CrawlSpider模塊 需改寫原來的def parse(self,response)方法
    from scrapy.spiders import CrawlSpider ,Rule
    
    #導(dǎo)入鏈接提取模塊
    from scrapy.linkextractors import LinkExtractor 
    from Geely.items import GeelyItem
    
    class BoyueSpider(CrawlSpider):
        name = 'BoYue'
        allowed_domains = ['car.autohome.com.cn']
        start_urls = ['https://car.autohome.com.cn/pic/series/3788.html']
    
        #如需要進(jìn)行頁面解釋則使用callback回調(diào)函數(shù) 因為有下一頁,所以我們需要跟進(jìn),這里使用follow令其為True
        rules = {
            Rule(LinkExtractor(allow=r'https://car.autohome.com.cn/pic/series/3788.+'), callback= 'parse_page', follow=True),
        } 
    
        def parse_page(self, response):
            catagory = response.xpath('//div[@class = "uibox"]/div/text()').get()
            srcs = response.xpath('//div[contains(@class,"uibox-con")]/ul/li//img/@src').getall()
    
            #map(函數(shù),參數(shù)二),將參數(shù)二中的每個都進(jìn)行函數(shù)計算并返回一個列表
            srcs = list(map(lambda x:x.replace('t_',''),srcs))
            srcs = list(map(lambda x:response.urljoin(x),srcs))
            yield GeelyItem(catagory=catagory, image_urls = srcs)
    
  4. 編寫PIPELINE:

    import os
    from urllib import request
    
    class GeelyPipeline(object):
    
        def __init__(self):
            #os.path.dirname()獲取當(dāng)前文件的路徑,os.path.join()獲取當(dāng)前目錄并拼接成新目錄
            self.path = os.path.join(os.path.dirname(__file__), 'images')
    
            # 判斷路徑是否存在
            if not os.path.exists(self.path):  
                os.mkdir(self.path)
    
        def process_item(self, item, spider):
    
            #分類存儲
            catagory = item['catagory']
            urls = item['image_urls']
    
            catagory_path = os.path.join(self.path, catagory)
    
            #如果沒有該路徑即創(chuàng)建一個
            if not os.path.exists(catagory_path): 
                os.mkdir(catagory_path)
    
            for url in urls:
                #以_進(jìn)行切割并取最后一個單元
                image_name = url.split('_')[-1] 
                request.urlretrieve(url,os.path.join(catagory_path,image_name))
    
            return item
    
  5. 編寫settings.py

    BOT_NAME = 'Geely'
    
    SPIDER_MODULES = ['Geely.spiders']
    NEWSPIDER_MODULE = 'Geely.spiders'
    
    # Obey robots.txt rules
    ROBOTSTXT_OBEY = False
    
    ITEM_PIPELINES = {
       'Geely.pipelines.GeelyPipeline': 1,
    }
    
  6. 讓項目跑起來:

    $ scrapy crawl BoYue
    
  7. 結(jié)果展示:

使用Images_pipeline進(jìn)行圖片下載

使用步驟:

  1. 定義好一個item,然后定義兩個屬性 image_urls 和 images。 image_urls是用來存儲需要下載的文件的url鏈接,列表類型;

  2. 當(dāng)文件下載完成后,會把文件下載的相關(guān)信息存儲到item的images屬性中。例如:下載路徑,下載url 和文件的效驗碼;

  3. 再配置文件settings.py中配置FILES_STORE,指定文件下載路徑;

  4. 啟動pipeline,在ITEM_PIPELINES中設(shè)置自定義的中間件?。?!

具體步驟

在上面的基礎(chǔ)上修改

  1. 修改settings.py

    ITEM_PIPELINES = {
       # 'Geely.pipelines.GeelyPipeline': 1,
       # 'scrapy.pipelines.images.ImagesPipeline': 1,
       'Geely.pipelines.GeelyImagesPipeline': 1,
    }
    
    #工程根目錄
    project_dir = os.path.dirname(__file__)
    #下載圖片存儲位置
    IMAGES_STORE = os.path.join(project_dir, 'images')
    
  2. 改寫pipelines,py

    # -*- coding: utf-8 -*-
    
    # Define your item pipelines here
    #
    # Don't forget to add your pipeline to the ITEM_PIPELINES setting
    # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
    
    import os
    from urllib import request
    
    from scrapy.pipelines.images import ImagesPipeline
    from Geely import settings
    
    # class GeelyPipeline(object):
    
    #     def __init__(self):
    #         #os.path.dirname()獲取當(dāng)前文件的路徑,os.path.join()獲取當(dāng)前目錄并拼接成新目錄
    #         self.path = os.path.join(os.path.dirname(__file__), 'images')
    
    #         # 判斷路徑是否存在
    #         if not os.path.exists(self.path):  
    #             os.mkdir(self.path)
    
    #     def process_item(self, item, spider):
    
    #         #分類存儲
    #         catagory = item['catagory']
    #         urls = item['image_urls']
    
    #         catagory_path = os.path.join(self.path, catagory)
    
    #         #如果沒有該路徑即創(chuàng)建一個
    #         if not os.path.exists(catagory_path): 
    #             os.mkdir(catagory_path)
    
    #         for url in urls:
    #             #以_進(jìn)行切割并取最后一個單元
    #             image_name = url.split('_')[-1] 
    #             request.urlretrieve(url,os.path.join(catagory_path,image_name))
    
    #         return item
    
    # 繼承ImagesPipeline
    class GeelyImagesPipeline(ImagesPipeline):
    
        # 該方法在發(fā)送下載請求前調(diào)用,本身就是發(fā)送下載請求的
        def get_media_requests(self, item, info):
    
            # super()直接調(diào)用父類對象
            request_objects = super(GeelyImagesPipeline, self).get_media_requests(item, info)
            for request_object in request_objects:
                request_object.item = item
            return request_objects
    
        def file_path(self, request, response=None, info=None):
    
            path = super(GeelyImagesPipeline, self).file_path(request, response, info)
    
            # 該方法是在圖片將要被存儲時調(diào)用,用于獲取圖片存儲的路徑
            catagory = request.item.get('catagory')
        
            # 拿到IMAGES_STORE
            images_stores = settings.IMAGES_STORE
            catagory_path = os.path.join(images_stores, catagory)
            
            #判斷文件名是否存在,如果不存在創(chuàng)建文件
            if not os.path.exists(catagory_path): 
                os.mkdir(catagory_path)
    
            image_name = path.replace('full/','')
            image_path = os.path.join(catagory+'/',image_name)
            
            return image_path
    
  3. 讓項目跑起來:

    $ scrapy crawl BoYue
    

將會得到與原來相同的結(jié)果?。。?!

此文章同時同步到我的個人博客緣來來來 ? Python爬蟲 --- 2.5 Scrapy之汽車之家爬蟲實踐

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • scrapy學(xué)習(xí)筆記(有示例版) 我的博客 scrapy學(xué)習(xí)筆記1.使用scrapy1.1創(chuàng)建工程1.2創(chuàng)建爬蟲模...
    陳思煜閱讀 13,087評論 4 46
  • 學(xué)習(xí)python時,爬蟲是一種簡單上手的方式,應(yīng)該也是一個必經(jīng)階段。本項目用Scrapy框架實現(xiàn)了抓取豆瓣top2...
    豌豆花下貓閱讀 1,567評論 0 6
  • 1 安裝Scrapy Scrapy是一個為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架。 可以應(yīng)用在包括數(shù)據(jù)挖掘...
    superzhan閱讀 1,558評論 0 11
  • 奇跡真的發(fā)生在了我的身上,感恩我的天使李茹,感恩我的朋友,感恩我的家人,感恩所以幫助我的人,謝謝你們!謝謝,謝謝,...
    Aries_e074閱讀 344評論 0 0
  • 每個人的生命中都有一個特殊的時刻,他就是為此而生。這個特殊的機遇,如果他能夠把握,將使他得以完成自己的使命—一個只...
    truth旭閱讀 270評論 0 0

友情鏈接更多精彩內(nèi)容