Scrapyを中断するには
Scrapyのクローリングは失敗があっても統計情報に記録しつつ最後まで実行する。ページの取得失敗やパイプラインでの処理失敗などで処理を中断したい場合は適切な例外をスローする必要がある。
例外はBuilt-in Exceptions referenceで示されている。
Spiderでの例外
典型的なサンプルがExceptionsのリファレンスに記載されている。response.bodyに帯域超過を示すメッセージがあれば、CloseSpider
をスローして終了するサンプル。
1 | def parse_page(self, response): |
ItemPipelineでの例外
典型的なサンプルがItemPipelineのリファレンスに記載されている。Itemにpriceという項目が無ければDropItem
をスローして終了するサンプル。
1 | from scrapy.exceptions import DropItem |
例外を発生させたときの挙動
公式チュートリアルのQuotesSpiderをカスタマイズして、Spiderを中断する例外をスローする。
コールバックのparser()
はただ中断される。
1 | import scrapy |
中断された場合、finish_reason
に指定したエラーメッセージが設定される。
1 | 2020-05-18 XX:XX:XX [scrapy.core.engine] INFO: Spider opened |
Using errbacks to catch exceptions in request processing
Requestプロセスの中で発生した例外はerrback
でその挙動を定義することができる。
ネットワークに関する典型的な例外をトラップする例が記載されている。サンプルではログ出力のみだが、前述の例外をスローして中断する処理を記述することができる。
1 | import scrapy |
SplashのLuaスクリプトの例外を処理する
SplashRequestから実行したLuaスクリプト内でerror()
を使って強制的にエラーを発生させている。Luaスクリプト内のエラーはSplashからHTTPのエラーコード400による応答でScrapyへ返却される。
ScrapyはSplashRequestに設定したerrback
でこのエラーをトラップし、CloseSpider
例外を発生させてSpiderを中断する。
1 | # -*- coding: utf-8 -*- |
Splashで400 Bad request to Splash
エラーなり、errback
でCloseSpider
例外を発生させ終了している。
1 | 2020-05-18 XX:XX:XX [scrapy.core.engine] DEBUG: Crawled (404) <GET http://quotes.toscrape.com/robots.txt> (referer: None) |