簡單的Python版本管理:pyenv Scrapy爬蟲入門教程一 Scrapy爬蟲入門教程二 Scrapy爬蟲入門教程三 Scrapy爬蟲入門教程四 Scrapy爬蟲入門教程五 Scrapy爬蟲入門教程六 Scrapy爬蟲入門教程七 Scrapy爬蟲入門教程八
Item Pipeline項目管道編寫自己的項目管道項目管道示例價格驗證和丟棄項目沒有價格將項目寫入MongoDB拍攝項目的屏幕截圖復制過濾器激活項目管道組件
開發環境: Python 3.6.0 版本
(當前最新) Scrapy 1.3.2 版本
(當前最新)
在項目被蜘蛛抓取后,它被發送到項目管道,它通過順序執行的幾個組件來處理它。
每個項目管道組件(有時稱為“Item Pipeline”)是一個實現簡單方法的Python類。他們接收一個項目并對其執行操作,還決定該項目是否應該繼續通過流水線或被丟棄并且不再被處理。
項目管道的典型用途是:
清理HTML數據驗證抓取的數據(檢查項目是否包含特定字段)檢查重復(并刪除)將刮取的項目存儲在數據庫中每個項目管道組件是一個Python類,必須實現以下方法: PRocess_item(self, item, spider)
對于每個項目管道組件調用此方法。process_item() 必須:返回一個帶數據的dict,返回一個Item (或任何后代類)對象,返回一個Twisted Deferred或者raise DropItemexception。丟棄的項目不再由其他管道組件處理。
參數:
item(Itemobject或dict) - 剪切的項目Spider(Spider對象) - 抓取物品的蜘蛛另外,它們還可以實現以下方法:
open_spider(self, spider)
當蜘蛛打開時調用此方法。
參數:
蜘蛛(Spider對象) - 打開的蜘蛛close_spider(self, spider)
當蜘蛛關閉時調用此方法。
參數:
蜘蛛(Spider對象) - 被關閉的蜘蛛from_crawler(cls, crawler)
如果存在,則調用此類方法以從a創建流水線實例Crawler。它必須返回管道的新實例。Crawler對象提供對所有Scrapy核心組件(如設置和信號)的訪問; 它是管道訪問它們并將其功能掛鉤到Scrapy中的一種方式。
參數:
crawler(Crawlerobject) - 使用此管道的crawler讓我們來看看以下假設的管道,它調整 price那些不包括增值稅(price_excludes_vat屬性)的項目的屬性,并刪除那些不包含價格的項目:
from scrapy.exceptions import DropItemclass PricePipeline(object): vat_factor = 1.15 def process_item(self, item, spider): if item['price']: if item['price_excludes_vat']: item['price'] = item['price'] * self.vat_factor return item else: raise DropItem("Missing price in %s" % item)將項目寫入JSON文件 以下管道將所有抓取的項目(來自所有蜘蛛)存儲到單個items.jl文件中,每行包含一個項目,以JSON格式序列化:
import jsonclass JsonWriterPipeline(object): def open_spider(self, spider): self.file = open('items.jl', 'wb') def close_spider(self, spider): self.file.close() def process_item(self, item, spider): line = json.dumps(dict(item)) + "/n" self.file.write(line) return item注意
JsonWriterPipeline的目的只是介紹如何編寫項目管道。如果您真的想要將所有抓取的項目存儲到JSON文件中,則應使用Feed導出。
在這個例子中,我們使用pymongo將項目寫入MongoDB。MongoDB地址和數據庫名稱在Scrapy設置中指定; MongoDB集合以item類命名。
這個例子的要點是顯示如何使用from_crawler()
方法和如何正確清理資源:
此示例演示如何從方法返回Deferredprocess_item()。它使用Splash來呈現項目網址的屏幕截圖。Pipeline請求本地運行的Splash實例。在請求被下載并且Deferred回調觸發后,它將項目保存到一個文件并將文件名添加到項目。
import scrapyimport hashlibfrom urllib.parse import quoteclass ScreenshotPipeline(object): """Pipeline that uses Splash to render screenshot of every Scrapy item.""" SPLASH_URL = "http://localhost:8050/render.png?url={}" def process_item(self, item, spider): encoded_item_url = quote(item["url"]) screenshot_url = self.SPLASH_URL.format(encoded_item_url) request = scrapy.Request(screenshot_url) dfd = spider.crawler.engine.download(request, spider) dfd.addBoth(self.return_item, item) return dfd def return_item(self, response, item): if response.status != 200: # Error happened, return item. return item # Save screenshot to file, filename will be hash of url. url = item["url"] url_hash = hashlib.md5(url.encode("utf8")).hexdigest() filename = "{}.png".format(url_hash) with open(filename, "wb") as f: f.write(response.body) # Store filename in item. item["screenshot_filename"] = filename return item用于查找重復項目并刪除已處理的項目的過濾器。假設我們的項目具有唯一的ID,但是我們的蜘蛛會返回具有相同id的多個項目:
from scrapy.exceptions import DropItemclass DuplicatesPipeline(object): def __init__(self): self.ids_seen = set() def process_item(self, item, spider): if item['id'] in self.ids_seen: raise DropItem("Duplicate item found: %s" % item) else: self.ids_seen.add(item['id']) return item要激活項目管道組件,必須將其類添加到 ITEM_PIPELINES設置,類似于以下示例:
ITEM_PIPELINES = { 'myproject.pipelines.PricePipeline': 300, 'myproject.pipelines.JsonWriterPipeline': 800,}您在此設置中分配給類的整數值確定它們運行的??順序:項目從較低值到較高值類。通常將這些數字定義在0-1000范圍內。
新聞熱點
疑難解答