# Spider 合約
> 譯者:[OSGeo 中國](https://www.osgeo.cn/)
0.15 新版功能.
注解
這是一個新功能(在Scrapy0.15中引入),可能會受到小功能/API更新的影響。檢查 [release notes](../news.html#news) 收到更新通知。
測試 Spider 會變得特別煩人,雖然沒有什么可以阻止你編寫單元測試,但是任務會很快變得很麻煩。Scrapy提供了一種綜合的方法,可以通過合同的方式測試你的 Spider 。
這允許您通過硬編碼一個示例URL來測試 Spider 的每個回調,并檢查回調如何處理響應的各種約束。每個合同的前綴都是 `@` 并包含在docstring中。請參見以下示例:
```py
def parse(self, response):
""" This function parses a sample response. Some contracts are mingled
with this docstring.
@url http://www.amazon.com/s?field-keywords=selfish+gene
@returns items 1 16
@returns requests 0 0
@scrapes Title Author Year Price
"""
```
此回調使用三個內置合同進行測試:
```py
class scrapy.contracts.default.UrlContract
```
本合同(合同) `@url` )設置檢查此spider的其他合同條件時使用的示例URL。本合同是強制性的。運行檢查時將忽略缺少此協定的所有回調::
```py
@url url
```
```py
class scrapy.contracts.default.ReturnsContract
```
本合同(合同) `@returns` )為 Spider 返回的項和請求設置下限和上限。上限是可選的:
```py
@returns item(s)|request(s) [min [max]]
```
```py
class scrapy.contracts.default.ScrapesContract
```
本合同(合同) `@scrapes` )檢查回調返回的所有項是否具有指定的字段::
```py
@scrapes field_1 field_2 ...
```
使用 [`check`](commands.html#std:command-check) 運行合同檢查的命令。
## 定制合同
如果您發現您需要比內置的零碎合同更多的電力,您可以使用 [`SPIDER_CONTRACTS`](settings.html#std:setting-SPIDER_CONTRACTS) 設置:
```py
SPIDER_CONTRACTS = {
'myproject.contracts.ResponseCheck': 10,
'myproject.contracts.ItemValidate': 10,
}
```
每個合同必須繼承自 [`scrapy.contracts.Contract`](#scrapy.contracts.Contract "scrapy.contracts.Contract") 可以覆蓋三種方法:
```py
class scrapy.contracts.Contract(method, *args)
```
| 參數: |
* **method** (_function_) -- 與合同關聯的回調函數
* **args** (_list_) -- 傳入docstring的參數列表(空格分隔)
|
| --- | --- |
```py
adjust_request_args(args)
```
這接收了 `dict` 作為包含請求對象的默認參數的參數。 [`Request`](request-response.html#scrapy.http.Request "scrapy.http.Request") 默認情況下使用,但可以使用 `request_cls` 屬性。如果鏈中的多個合同定義了此屬性,則使用最后一個。
必須返回相同或修改過的版本。
```py
pre_process(response)
```
這允許在將樣本請求傳遞到回調之前,對從該請求接收的響應進行各種檢查。
```py
post_process(output)
```
這允許處理回調的輸出。迭代器在傳遞給這個Hook之前被轉換為列表化的。
這里是一個演示合同,它檢查在收到的響應中是否存在自定義頭。提高 `scrapy.exceptions.ContractFail` 為了讓故障得到完美的打印:
```py
from scrapy.contracts import Contract
from scrapy.exceptions import ContractFail
class HasHeaderContract(Contract):
""" Demo contract which checks the presence of a custom header
@has_header X-CustomHeader
"""
name = 'has_header'
def pre_process(self, response):
for header in self.args:
if header not in response.headers:
raise ContractFail('X-CustomHeader not present')
```
- 簡介
- 第一步
- Scrapy at a glance
- 安裝指南
- Scrapy 教程
- 實例
- 基本概念
- 命令行工具
- Spider
- 選擇器
- 項目
- 項目加載器
- Scrapy shell
- 項目管道
- Feed 導出
- 請求和響應
- 鏈接提取器
- 設置
- 例外情況
- 內置服務
- Logging
- 統計數據集合
- 發送電子郵件
- 遠程登錄控制臺
- Web服務
- 解決具體問題
- 常見問題
- 調試spiders
- Spider 合約
- 常用做法
- 通用爬蟲
- 使用瀏覽器的開發人員工具進行抓取
- 調試內存泄漏
- 下載和處理文件和圖像
- 部署 Spider
- AutoThrottle 擴展
- Benchmarking
- 作業:暫停和恢復爬行
- 延伸 Scrapy
- 體系結構概述
- 下載器中間件
- Spider 中間件
- 擴展
- 核心API
- 信號
- 條目導出器
- 其余所有
- 發行說明
- 為 Scrapy 貢獻
- 版本控制和API穩定性