ITEM PIPELINE用法詳解:
ITEM PIPELINE作用:
- 清理HTML數據
- 驗證爬取的數據(檢查item包含某些字段)
- 去重(並丟棄)【預防數據去重,真正去重是在url,即請求階段做】
- 將爬取結果保存到數據庫中
ITEM PIPELINE核心方法(4個)
(1)、open_spider(spider)
(2)、close_spider(spider)
(3)、from_crawler(cls,crawler)
(4)、process_item(item,spider)
下面小伙伴們我們依次來分析:
1、open_spider(spider) 【參數spider 即被開啟的Spider對象】
該方法非必需,在Spider開啟時被調用,主要做一些初始化操作,如連接數據庫等
2、close_spider(spider)【參數spider 即被關閉的Spider對象】
該方法非必需,在Spider關閉時被調用,主要做一些如關閉數據庫連接等收尾性質的工作
3、from_crawler(cls,crawler)【參數一:Class類 參數二:crawler對象】
該方法非必需,Spider啟用時調用,早於open_spider()方法,是一個類方法,用@classmethod標識,它與__init__函有關,這里我們不詳解(一般我們不對它進行修改)
4、process_item(item,spider)【參數一:被處理的Item對象 參數二:生成該Item的Spider對象】
該方法必需實現,定義的Item pipeline會默認調用該方法對Item進行處理,它返回Item類型的值或者拋出DropItem異常
實例分析(以下實例來自官網:https://doc.scrapy.org/en/latest/topics/item-pipeline.html)
1 from scrapy.exceptions import DropItem 2 3 class PricePipeline(object): 4 5 vat_factor = 1.15 6 7 def process_item(self, item, spider): 8 if item['price']: 9 if item['price_excludes_vat']: 10 item['price'] = item['price'] * self.vat_factor 11 return item 12 else: 13 raise DropItem("Missing price in %s" % item)
代碼分析:
首先定義了一個PricePipeline類
定義了增值稅稅率因子為1.15
主函數process_item方法實現了如下功能:判斷Item中的price字段,如沒計算增值稅,則乘以1.15,並返回Item,否則直接拋棄
總結:該方法要么return item給后邊的管道處理,要么拋出異常
數據去重
1 from scrapy.exceptions import DropItem 2 3 class DuplicatesPipeline(object): 4 5 def __init__(self): 6 self.ids_seen = set() 7 8 def process_item(self, item, spider): 9 if item['id'] in self.ids_seen: 10 raise DropItem("Duplicate item found: %s" % item) 11 else: 12 self.ids_seen.add(item['id']) 13 return item
代碼分析:
首先定義了一個DuplicatesPipeline類
這里比上面多了一個初始化函數__init__,set()---去重函數
主函數process_item方法首先判斷item數據中的id是否重復,重復的就將其拋棄,否則就增加到id,然后傳給下個管道
將數據寫入文件
1 import json 2 3 class JsonWriterPipeline(object): 4 5 def open_spider(self, spider): 6 self.file = open('items.jl', 'w') 7 8 def close_spider(self, spider): 9 self.file.close() 10 11 def process_item(self, item, spider): 12 line = json.dumps(dict(item)) + "\n" 13 self.file.write(line) 14 return item
代碼分析:
首先我們定義了一個JsonWritePipeline類
定義了三個函數:
first:open_spider()在Spider開啟時啟用作用很簡單即打開文件,准備寫入數據
second:close_spider()在Spider關閉時啟用作用也很簡單即關閉文件
third(主要):process_items()作用如下首先將item轉換為字典類型,在用json.dumps()序列化為json字符串格式,再寫入文件,最后返回修改的item給下一個管道
綜合實例
1 import pymongo 2 3 class MongoPipeline(object): 4 5 collection_name = 'scrapy_items' 6 7 def __init__(self, mongo_uri, mongo_db): 8 self.mongo_uri = mongo_uri 9 self.mongo_db = mongo_db 10 11 @classmethod 12 def from_crawler(cls, crawler): 13 return cls( 14 mongo_uri=crawler.settings.get('MONGO_URI'), 15 mongo_db=crawler.settings.get('MONGO_DATABASE', 'items') 16 ) 17 18 def open_spider(self, spider): 19 self.client = pymongo.MongoClient(self.mongo_uri) 20 self.db = self.client[self.mongo_db] 21 22 def close_spider(self, spider): 23 self.client.close() 24 25 def process_item(self, item, spider): 26 self.db[self.collection_name].insert(dict(item)) 27 return item
代碼分析:
首先我們定義了一個MongoPipeline類
這里我們修改了初始化函數__init__,給出了存儲到Mongodb的鏈接地址和數據庫名稱所以更改了from_crawler()工廠函數函數(生產它的對象),這里指定了鏈接地址和數據表名稱
最后我們定義了三個函數:
first:open_spider()在Spider開啟時啟用作用是打開mongodb數據庫
second:close_spider()在Spider關閉時啟用作用是關閉數據庫
third:process_items()作用如下在數據庫中插入item
項目實戰:(我們以58同城鎮江房屋出租為例)抓取出租信息的標題、價格、詳情頁的url
我是在ubuntu16.04環境下跑的
啟動終端並激活虛擬環境:source course_python3.5/bin/activate
創建一個新目錄project:mkdir project
創建項目:scrapy startproject city58-----cd city58----創建爬蟲(這里小伙伴們注意項目名不能與爬蟲名重名)scrapy genspider city58_test
下面我們正式開始
(1)、修改items.py
(2)修改city58_test.py文件(這里我們使用pyquery選擇器)
(3)、重點來了,修改pipelines.py文件,小伙伴們可參考上面的案例分析
(4)最后通過settings.py啟動pipeline
這里向小伙伴們科普一個小知識點:后面的數字是優先級,數字越小,越優先執行
(5)項目運行結果(部分)----下次小伙伴們想了解出租信息可以找我,我幫你秒下。哈哈!
並且我們可以在同級目錄下找到我們寫入的文件
總結:
(1)、首先了解了管道的作用
(2)、掌握了核心的方法,其中特別是process_item()方法
(3)、最后我們通過實例和項目進行實戰,后面我們會繼續學習如何使用管道進行高級的操作,敬請期待,記得最后一定要在配置文件中開啟Spider中間件