爬取伯樂在線文章(五)itemloader


ItemLoader

在我們執行scrapy爬取字段中,會有大量的CSS或是Xpath代碼,當要爬取的網站多了,要維護起來很麻煩,為解決這類問題,我們可以根據scrapy提供的loader機制。

導入ItemLoader

from scrapy.loader import ItemLoader

實例化ItemLoader對象

要使用Itemloader,必須先將它實例化。查看一下ItemLoader的源碼,有2個重要的傳入參數,item和response

        # 通過ItemLoader對象實例化item
        item_loader = ItemLoader(item=JobBoleArticleItem(), response=response)
        # 針對CSS選擇器
        item_loader.add_css('title', '.entry-header h1::text')
        item_loader.add_css('create_date', '.entry-meta .entry-meta-hide-on-mobile::text')
        item_loader.add_css('praise_num', '.vote-post-up h10::text')
        item_loader.add_css('collect_num', '.post-adds .bookmark-btn::text')
        item_loader.add_css('comment_num', '.post-adds .hide-on-480::text')
        # 針對直接取值的情況
        item_loader.add_value('url', response.url)
        item_loader.add_value('url_object_id', get_md5(response.url))
        item_loader.add_value('front_image_url', [front_image_url])
        # 把結果返回給item對象
        article_item = item_loader.load_item()        

Debug調試查看情況

調用默認的item方法目前有2個問題:

(1)默認情況下傳入的都是一些list

(2)像parise_num和comment_num傳入的一些值我們還需要在進行一次過濾,加一些處理函數

MapCompose

如果解決上面兩個問題?如何取list第一個值,如何在某些字段上加一些處理函數?為了解決這個問題,我們需要重新修改items.py,需要導入MapCompose類

from scrapy.loader.processors import MapCompose

MapCompose里面可以傳入任意多的函數,也可以傳入一些lambda表達式

title = scrapy.Field(
        # 代表當item傳入值的時候,我們可以對這些值進行一些預處理,MapCompose可以傳入任意多個函數
        input_processor = MapCompose(lambda x:x+"-jobbole")
    )

此時在進行Debug調試,title上會添加-jobbole

我們可以在加入一個函數,現在MapCompose里面有一個lambda表達式,一個函數,Debug看是否能夠連續處理

Debug

經測試可以從左到右依次連續進行處理

TakeFirst

那如何獲取list中的第一個值,此時需要TakeFirst函數

導入

from scrapy.loader.processors import MapCompose, TakeFirst

調用

 create_date = scrapy.Field(
        input_processor = MapCompose(date_convert),
        output_processor = TakeFirst()
    )

Debug調試,此時獲取的create_time就是一個date類型的值了而不是一個list

自定義ItemLoader

如果所有的字段都去第一個值,是否每個字段都需要添加

output_processor = TakeFirst()

此時太麻煩,我們可以自己定義一個ItemLoader,需要繼承scrapy的ItemLoader類

from scrapy.loader import ItemLoader
class ArticleItemLoader(ItemLoader):
    pass

查看ItemLoader的源碼,有一個默認的

修改默認的default_output_processor方法

class ArticleItemLoader(ItemLoader):
    default_output_processor = TakeFirst()

在修改我們爬蟲里面ItemLoader為我們自定義的ItemLoader,在jobbole.py里面修改

from EnterpriseSpider.items import JobBoleArticleItem, ArticleItemLoader
        # 通過ItemLoader對象實例化item
        item_loader = ArticleItemLoader(item=JobBoleArticleItem(), response=response)

Debug調試,此時item返回的是單個的值而不是一個list

圖片下載處理

此時返回的front_image_url是一個字符串,此時在交給ImagePipeline進行下載的時候就會拋出異常,我們必須覆蓋掉默認的output_processor方法

def return_value(value):
    return value
 front_image_url = scrapy.Field(
        output_processor=MapCompose(return_value)
    )

 

此時還需要修改插入數據庫的語句,還需要修改ArticleImagePipeline

class ArticleImagePipeline(ImagesPipeline):
    def item_completed(self, results, item, info):
        if "front_image_url" in item:
            for ok, value in results:
                image_file_path = value["path"]
            item["front_image_url"] = image_file_path
        return item

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

default_output_processor


免責聲明!

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



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