# 擴展
> 譯者:[OSGeo 中國](https://www.osgeo.cn/)
擴展框架提供了一種將您自己的自定義功能插入到Scrapy中的機制。
擴展只是在初始化擴展時,在scrapy啟動時實例化的常規類。
## 擴展設置
擴展使用 [Scrapy settings](settings.html#topics-settings) 管理他們的設置,就像任何其他零碎的代碼一樣。
擴展通常會在其設置前面加上自己的名稱,以避免與現有(和將來)擴展沖突。例如,要處理的假設擴展 [Google Sitemaps](https://en.wikipedia.org/wiki/Sitemaps) 將使用如下設置 `GOOGLESITEMAP_ENABLED` , `GOOGLESITEMAP_DEPTH` 等等。
## 加載和激活擴展
通過實例化擴展類的單個實例,可以在啟動時加載和激活擴展。因此,所有擴展初始化代碼都必須在類構造函數中執行。( `__init__` 方法)。
若要使擴展名可用,請將其添加到 [`EXTENSIONS`](settings.html#std:setting-EXTENSIONS) 設置你的剪貼設置。在 [`EXTENSIONS`](settings.html#std:setting-EXTENSIONS) ,每個擴展都由一個字符串表示:擴展類名的完整python路徑。例如::
```py
EXTENSIONS = {
'scrapy.extensions.corestats.CoreStats': 500,
'scrapy.extensions.telnet.TelnetConsole': 500,
}
```
如你所見, [`EXTENSIONS`](settings.html#std:setting-EXTENSIONS) 設置是一個dict,其中鍵是擴展路徑,它們的值是定義擴展的順序。 _loading_ 秩序。這個 [`EXTENSIONS`](settings.html#std:setting-EXTENSIONS) 設置與合并 [`EXTENSIONS_BASE`](settings.html#std:setting-EXTENSIONS_BASE) 在scrappy中定義的設置(不打算被重寫),然后按順序排序,以獲得已啟用擴展的最終排序列表。
由于擴展通常不相互依賴,因此在大多數情況下,它們的加載順序是不相關的。這就是為什么 [`EXTENSIONS_BASE`](settings.html#std:setting-EXTENSIONS_BASE) 設置以相同的順序定義所有擴展( `0` )但是,如果需要添加依賴于已加載的其他擴展的擴展,則可以利用此功能。
## 可用、啟用和禁用擴展
并非所有可用的擴展都將啟用。其中一些通常取決于特定的設置。例如,HTTP緩存擴展在默認情況下是可用的,但在 [`HTTPCACHE_ENABLED`](downloader-middleware.html#std:setting-HTTPCACHE_ENABLED) 設置設置。
## 禁用擴展
為了禁用默認啟用的擴展(即包含在 [`EXTENSIONS_BASE`](settings.html#std:setting-EXTENSIONS_BASE) 設置)必須將其順序設置為 `None` . 例如::
```py
EXTENSIONS = {
'scrapy.extensions.corestats.CoreStats': None,
}
```
## 編寫自己的擴展名
每個擴展都是一個Python類。 Scrapy 擴展(也包括中間產品和管道)的主要入口點是 `from_crawler` 類方法,它接收 `Crawler` 實例。通過爬蟲對象,您可以訪問設置、信號、統計信息,還可以控制爬行行為。
通常,擴展連接到 [signals](signals.html#topics-signals) 并執行由它們觸發的任務。
最后,如果 `from_crawler` 方法引發 [`NotConfigured`](exceptions.html#scrapy.exceptions.NotConfigured "scrapy.exceptions.NotConfigured") 異常,擴展將被禁用。否則,將啟用擴展。
### 樣本擴展
在這里,我們將實現一個簡單的擴展來說明前一節中描述的概念。此擴展將每次記錄一條消息:
* Spider 被打開了
* Spider 被關閉了
* 特定數量的物品被刮掉
擴展將通過 `MYEXT_ENABLED` 設置和項目數將通過 `MYEXT_ITEMCOUNT` 設置。
這是這種擴展的代碼:
```py
import logging
from scrapy import signals
from scrapy.exceptions import NotConfigured
logger = logging.getLogger(__name__)
class SpiderOpenCloseLogging(object):
def __init__(self, item_count):
self.item_count = item_count
self.items_scraped = 0
@classmethod
def from_crawler(cls, crawler):
# first check if the extension should be enabled and raise
# NotConfigured otherwise
if not crawler.settings.getbool('MYEXT_ENABLED'):
raise NotConfigured
# get the number of items from settings
item_count = crawler.settings.getint('MYEXT_ITEMCOUNT', 1000)
# instantiate the extension object
ext = cls(item_count)
# connect the extension object to signals
crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened)
crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed)
crawler.signals.connect(ext.item_scraped, signal=signals.item_scraped)
# return the extension object
return ext
def spider_opened(self, spider):
logger.info("opened spider %s", spider.name)
def spider_closed(self, spider):
logger.info("closed spider %s", spider.name)
def item_scraped(self, item, spider):
self.items_scraped += 1
if self.items_scraped % self.item_count == 0:
logger.info("scraped %d items", self.items_scraped)
```
## 內置擴展引用
### 通用擴展
#### 日志統計擴展
```py
class scrapy.extensions.logstats.LogStats
```
記錄基本的統計信息,如已爬網的頁面和已擦除的項目。
#### 核心統計擴展
```py
class scrapy.extensions.corestats.CoreStats
```
啟用核心統計信息集合,前提是已啟用統計信息集合(請參見 [統計數據集合](stats.html#topics-stats) )
#### Telnet控制臺擴展
```py
class scrapy.extensions.telnet.TelnetConsole
```
提供一個telnet控制臺,用于進入當前運行的scrapy進程中的python解釋器,這對于調試非常有用。
telnet控制臺必須由 [`TELNETCONSOLE_ENABLED`](settings.html#std:setting-TELNETCONSOLE_ENABLED) 設置,服務器將偵聽中指定的端口 [`TELNETCONSOLE_PORT`](telnetconsole.html#std:setting-TELNETCONSOLE_PORT) .
#### 內存使用擴展
```py
class scrapy.extensions.memusage.MemoryUsage
```
注解
此擴展在Windows中不起作用。
監視運行spider的scrapy進程使用的內存,并:
1. 超過某個值時發送通知電子郵件
2. 當 Spider 超過某個值時關閉 Spider
當達到某個警告值時,可以觸發通知電子郵件。( [`MEMUSAGE_WARNING_MB`](settings.html#std:setting-MEMUSAGE_WARNING_MB) )當達到最大值時( [`MEMUSAGE_LIMIT_MB`](settings.html#std:setting-MEMUSAGE_LIMIT_MB) )這也會導致 Spider 被關閉, Scrapy 過程被終止。
此擴展由 [`MEMUSAGE_ENABLED`](settings.html#std:setting-MEMUSAGE_ENABLED) 設置,可以使用以下設置進行配置:
* [`MEMUSAGE_LIMIT_MB`](settings.html#std:setting-MEMUSAGE_LIMIT_MB)
* [`MEMUSAGE_WARNING_MB`](settings.html#std:setting-MEMUSAGE_WARNING_MB)
* [`MEMUSAGE_NOTIFY_MAIL`](settings.html#std:setting-MEMUSAGE_NOTIFY_MAIL)
* [`MEMUSAGE_CHECK_INTERVAL_SECONDS`](settings.html#std:setting-MEMUSAGE_CHECK_INTERVAL_SECONDS)
#### 內存調試器擴展
```py
class scrapy.extensions.memdebug.MemoryDebugger
```
調試內存使用情況的擴展。它收集以下信息:
* python垃圾收集器未收集的對象
* 不應該保留的對象。有關詳細信息,請參閱 [使用調試內存泄漏 trackref](leaks.html#topics-leaks-trackrefs)
要啟用此擴展,請打開 [`MEMDEBUG_ENABLED`](settings.html#std:setting-MEMDEBUG_ENABLED) 設置。信息將存儲在統計信息中。
#### 關閉星形延長件
```py
class scrapy.extensions.closespider.CloseSpider
```
當滿足某些條件時,使用每個條件的特定關閉原因自動關閉 Spider 。
關閉 Spider 的條件可以通過以下設置進行配置:
* [`CLOSESPIDER_TIMEOUT`](#std:setting-CLOSESPIDER_TIMEOUT)
* [`CLOSESPIDER_ITEMCOUNT`](#std:setting-CLOSESPIDER_ITEMCOUNT)
* [`CLOSESPIDER_PAGECOUNT`](#std:setting-CLOSESPIDER_PAGECOUNT)
* [`CLOSESPIDER_ERRORCOUNT`](#std:setting-CLOSESPIDER_ERRORCOUNT)
##### CLOSESPIDER_TIMEOUT
違約: `0`
指定秒數的整數。如果 Spider 保持打開超過該秒數,它將自動關閉,原因如下 `closespider_timeout` . 如果為零(或未設置), Spider 將不會在超時時關閉。
##### CLOSESPIDER_ITEMCOUNT
違約: `0`
指定若干項的整數。如果spider的抓取量超過該數量,并且這些項目通過項目管道,那么spider將關閉,原因是 `closespider_itemcount` . 當前在下載器隊列中的請求(最多 [`CONCURRENT_REQUESTS`](settings.html#std:setting-CONCURRENT_REQUESTS) 請求)仍在處理中。如果為零(或未設置), Spider 將不會被通過的項目數關閉。
##### CLOSESPIDER_PAGECOUNT
0.11 新版功能.
違約: `0`
指定要爬網的最大響應數的整數。如果 Spider 爬得比這個還多, Spider 會被關閉的,原因是 `closespider_pagecount` . 如果為零(或未設置), Spider 將不會被爬行響應的數量關閉。
##### CLOSESPIDER_ERRORCOUNT
0.11 新版功能.
違約: `0`
一個整數,指定關閉 Spider 之前要接收的最大錯誤數。如果spider生成的錯誤數量超過該數量,則會關閉它并說明原因。 `closespider_errorcount` . 如果為零(或未設置), Spider 將不會被錯誤數關閉。
#### StatsMailer擴展
```py
class scrapy.extensions.statsmailer.StatsMailer
```
這個簡單的擴展可用于在域完成抓取時發送通知電子郵件,包括收集到的殘缺統計信息。電子郵件將發送給 [`STATSMAILER_RCPTS`](settings.html#std:setting-STATSMAILER_RCPTS) 設置。
### 調試擴展
#### 堆棧跟蹤轉儲擴展
```py
class scrapy.extensions.debug.StackTraceDump
```
當 [SIGQUIT](https://en.wikipedia.org/wiki/SIGQUIT) 或 [SIGUSR2](https://en.wikipedia.org/wiki/SIGUSR1_and_SIGUSR2) 接收到信號。轉儲的信息如下:
1. 發動機狀態(使用 `scrapy.utils.engine.get_engine_status()` )
2. 實時參考(請參見 [使用調試內存泄漏 trackref](leaks.html#topics-leaks-trackrefs) )
3. 所有線程的堆棧跟蹤
在轉儲堆棧跟蹤和引擎狀態后,碎片進程繼續正常運行。
此擴展僅在符合POSIX的平臺(即,不是Windows)上工作,因為 [SIGQUIT](https://en.wikipedia.org/wiki/SIGQUIT) 和 [SIGUSR2](https://en.wikipedia.org/wiki/SIGUSR1_and_SIGUSR2) Windows上沒有信號。
至少有兩種方法可以將Scrapy [SIGQUIT](https://en.wikipedia.org/wiki/SIGQUIT) 信號:
1. 按ctrl-while a scrapy process is running(Linux only?)
2. 通過運行此命令(假設 `<pid>` 是 Scrapy 流程的流程ID)::
```py
kill -QUIT <pid>
```
#### 調試器擴展
```py
class scrapy.extensions.debug.Debugger
```
調用一個 [Python debugger](https://docs.python.org/2/library/pdb.html) 當 [SIGUSR2](https://en.wikipedia.org/wiki/SIGUSR1_and_SIGUSR2) 接收到信號。退出調試程序后,碎片處理程序繼續正常運行。
有關詳細信息,請參閱 [Debugging in Python](https://pythonconquerstheuniverse.wordpress.com/2009/09/10/debugging-in-python/) .
此擴展僅在符合POSIX的平臺(即,不是Windows)上工作。
- 簡介
- 第一步
- Scrapy at a glance
- 安裝指南
- Scrapy 教程
- 實例
- 基本概念
- 命令行工具
- Spider
- 選擇器
- 項目
- 項目加載器
- Scrapy shell
- 項目管道
- Feed 導出
- 請求和響應
- 鏈接提取器
- 設置
- 例外情況
- 內置服務
- Logging
- 統計數據集合
- 發送電子郵件
- 遠程登錄控制臺
- Web服務
- 解決具體問題
- 常見問題
- 調試spiders
- Spider 合約
- 常用做法
- 通用爬蟲
- 使用瀏覽器的開發人員工具進行抓取
- 調試內存泄漏
- 下載和處理文件和圖像
- 部署 Spider
- AutoThrottle 擴展
- Benchmarking
- 作業:暫停和恢復爬行
- 延伸 Scrapy
- 體系結構概述
- 下載器中間件
- Spider 中間件
- 擴展
- 核心API
- 信號
- 條目導出器
- 其余所有
- 發行說明
- 為 Scrapy 貢獻
- 版本控制和API穩定性