スパイダー コントラクト¶
バージョン 0.15 で追加.
注釈
これは新機能(Scrapy 0.15で導入)であり、細かい機能やAPIの更新が行われる場合があります。更新を知る為に リリースノート をチェックしてください。
スパイダーのテストは特にウンコで、単体テストを書くのは楽チンだけど、テスト作業はマンドクサ。Scrapyはコントラクト(訳注:contract;取り決め)によってスパイダーを統一的にテストする方法を提供します。
これにより、サンプルURLをハードコーディングしてスパイダーの各コールバックをテストし、コールバックが応答を処理する方法のさまざまな制約を確認できます。各コントラクトはdocstringに含め、各コントラクトの先頭には @
が付けられています。次の例をご覧ください:
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
"""
このコールバックは、3つの組み込みコントラクトを使用してテストされます。:
-
class
scrapy.contracts.default.
UrlContract
¶ このコントラクト(
@url
)は、このスパイダーの他のコントラクト条件をチェックするときに使用されるサンプルURLを設定します。 このコントラクトは必須です。 チェックを実行する場合、このコントラクトがないコールバックはすべて無視されます:@url url
-
class
scrapy.contracts.default.
CallbackKeywordArgumentsContract
¶ このコントラクト(
@cb_kwargs
)は、サンプルリクエストのcb_kwargs
属性を設定します。 有効なJSON辞書である必要があります。:@cb_kwargs {"arg1": "value1", "arg2": "value2", ...}
-
class
scrapy.contracts.default.
ReturnsContract
¶ このコントラクト(
@returns
)は、スパイダーによって返されるアイテムとリクエストの下限と上限を設定します。 上限はオプションです。:@returns item(s)|request(s) [min [max]]
-
class
scrapy.contracts.default.
ScrapesContract
¶ このコントラクト(
@scrapes
)は、コールバックによって返されたすべてのアイテムに指定されたフィールドがあることを確認します。:@scrapes field_1 field_2 ...
check
コマンドを使用して、コントラクトチェックを実行します。
カスタム コントラクト¶
うぬはチカラが欲しくないか? 組み込みScrapyコントラクトよりも多くのチカラを。その場合は、 SPIDER_CONTRACTS
設定を使用して、プロジェクトに独自のコントラクトを作成してロードできます:
SPIDER_CONTRACTS = {
'myproject.contracts.ResponseCheck': 10,
'myproject.contracts.ItemValidate': 10,
}
各コントラクトは Contract
から継承する必要があり、3つのメソッドをオーバーライドできます。:
-
class
scrapy.contracts.
Contract
(method, *args)¶ - パラメータ
method (function) -- コントラクトが関連付けられているコールバック関数
args (list) -- docstringに渡される引数のリスト(空白区切り)
-
adjust_request_args
(args)¶ これは、リクエストオブジェクトのデフォルト引数を含む引数として
dict
を受け取ります。Request
はデフォルトで使用されますが、これはrequest_cls
属性で変更できます。 チェーン内の複数のコントラクトにこの属性が定義されている場合、最後のコントラクトが使用されます。同じまたは変更されたバージョンを返す必要があります。
-
pre_process
(response)¶ これにより、コールバックに渡される前に、サンプルリクエストから受信したレスポンスのさまざまなチェックをフックすることを許します。
-
post_process
(output)¶ これにより、コールバックの出力を処理できます。 イテレータは、このフックに渡される前に変換されてリスト化されます。
期待どおりで無い場合、 pre_process
または post_process
から ContractFail
例外が送出されます。
以下に、受信した応答のカスタムヘッダーの存在を確認するデモ・コントラクトを示します。:
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 check
実行の検出¶
scrapy check
が実行されているとき、 SCRAPY_CHECK
環境変数を true
文字列に設定します。 scrapy check
が使用されている場合、 os.environ を使用して、スパイダーや設定に変更を加えることができます。:
import os
import scrapy
class ExampleSpider(scrapy.Spider):
name = 'example'
def __init__(self):
if os.environ.get('SCRAPY_CHECK'):
pass # Do some scraper adjustments when a check is running