広範なクロール¶
Scrapyのデフォルトは、特定のサイトをクロールするために最適化されています。 多くの場合、これらのサイトは単一のScrapyスパイダーで処理されますが、これは必要または必須ではありません(たとえば、スロー(throw)される特定のサイトを処理する汎用スパイダーがあります)。
この「フォーカスクロール」に加えて、多数の(潜在的に無制限の)ドメインをカバーする別の一般的なタイプのクロールがあり、ドメインが完全にクロールされたときまたは、実行するリクエストがなくなったときに停止するのではなく、時間またはその他の任意の制約によってのみ制限されます。これらは広範なクロール(broad crawls)と呼ばれ、検索エンジンで採用されている典型的なクローラーです。
これらは、広範なクロールでよく見られる一般的なプロパティです:
特定のサイトセットではなく、多くのドメイン(多くの場合、無制限)をクロールします。
ドメインをクロールする必要はありません。実行するのは非現実的(または不可能)であるため、代わりにクロールを時間またはクロールされるページ数で制限します。
(多くの抽出ルールを持つ非常に複雑なスパイダーとは対照的に、)多くの場合、データは別の段階で後処理されることが多いため、ロジックが単純です。
多くのドメインを並列してクロールします。これにより、特定のサイトの制約によって制限されないため、クロール速度が向上します(各サイトはポライトネスを尊重するためにゆっくりクロールされますが、多くのサイトが並行してクロールされます)
前述のように、Scrapyのデフォルト設定は、広範なクロールではなく、集中的なクロール用に最適化されています。ただし、非同期アーキテクチャのため、Scrapyは高速で広範なクロールを実行するのに非常に適しています。ここでは、Scrapyを使用して幅広いクロールを行う際に留意する必要があるいくつかの事項を要約し、効率的な幅広いクロールを実現するために調整するScrapy設定の具体的な提案を行います。
正しい SCHEDULER_PRIORITY_QUEUE
の使用¶
Scrapyのデフォルトのスケジューラ優先度キューは 'scrapy.pqueues.ScrapyPriorityQueue'
です。 単一ドメインクロール中に最適に機能します。多くの異なるドメインを並行してクロールするとうまく機能しません
推奨される優先度キューを適用するには:
SCHEDULER_PRIORITY_QUEUE = 'scrapy.pqueues.DownloaderAwarePriorityQueue'
並行性を高める¶
同時実行性は、並行して処理されるリクエストの数です。グローバル制限( CONCURRENT_REQUESTS
)と、ドメイン( CONCURRENT_REQUESTS_PER_DOMAIN
)またはIP( CONCURRENT_REQUESTS_PER_IP
)ごとに設定できる追加の制限があります。
注釈
スケジューラの優先度キューの 広範なクロールにお勧めのキュー は CONCURRENT_REQUESTS_PER_IP
をサポートしていません。
Scrapyのデフォルトのグローバル同時実行制限は、多くの異なるドメインを並行してクロールするのには適していないため、増やすことをお勧めします。どれだけ増やすかは、クローラーが使用できるCPUとメモリの量によって異なります。
良い出発点は 100
です:
CONCURRENT_REQUESTS = 100
しかし、それを見つけるための最良の方法は、いくつかの試行を行い、ScrapyプロセスがCPUの限界に達する同時性を特定することです。最適なパフォーマンスを得るには、CPU使用率が80〜90%の同時実行性を選択する必要があります。
並行性を高めると、メモリ使用量も増えます。メモリ使用量が懸念される場合は、それに応じてグローバル同時実行制限を下げる必要があります。
Twisted IOスレッド・プールの最大サイズを増やす¶
現在、Scrapyは、スレッド・プールの使用をブロックする方法でDNS解決を行います。 同時実行レベルが高いと、クロールが遅くなったり、DNSリゾルバーのタイムアウトに失敗したりすることさえあります。可能な解決策はDNSクエリを処理するスレッドの数を増やす事です。そうすれば、DNSキューはより速く処理され、接続の確立とクロール全体が高速化されます。
スレッド・プールの最大サイズを増やすには:
REACTOR_THREADPOOL_MAXSIZE = 20
あなた独自のDNSをセットアップする¶
複数のクロール・プロセスと単一の中央DNSがある場合、DNSサーバーに対するDoS攻撃のように動作し、ネットワーク全体の速度を低下させたり、マシンをブロックすることさえあります。この設定を回避するには、ローカルキャッシュを備えた独自のDNSサーバーと、OpenDNSやVerizonなどの大規模なDNSのアップ・ストリームを使用します。
ログレベルを下げる¶
広範なクロールを行う場合、多くの場合、取得するクロール・レートと検出されたエラーのみに関心があります。 これらの統計は、 INFO
ログ・レベルを使用しているときにScrapyによって報告されます。 CPU資源(およびログ・ストレージ要件)を節約するために、本番環境で大規模な広範なクロールを実行するときに DEBUG
ログ・レベルを使用しないでください。(広範囲の)クローラーの開発時では DEBUG
レベルを使用しても問題ありません。
ログレベルを設定するには:
LOG_LEVEL = 'INFO'
クッキーを無効にする¶
本当に 必要がない限り、クッキーを無効にします。クッキーは、広範なクロールを実行するときに必要ない場合が多く(検索エンジンク・ローラーはそれらを無視します)、CPUサイクルを節約し、Scrapyクローラーのメモリ・フット・プリントを削減することでパフォーマンスを向上させます。
クッキーを無効にするには:
COOKIES_ENABLED = False
再試行を無効にする¶
失敗したHTTPリクエストを再試行すると、特にサイトが原因でレスポンスが非常に遅い(または失敗する)場合、クロールが大幅に遅くなる可能性があります。そのため、タイム・アウト・エラーが何度も再試行され、不必要にクローラー容量が他のドメインで再利用できなくなります。
再試行を無効にするには:
RETRY_ENABLED = False
ダウンロードのタイムアウトを短縮¶
非常に遅い接続からクロールする場合を除き(広範なクロールの場合はそうではありません)、ダウンロード・タイムアウトを減らして、スタックしたリクエストを迅速に破棄し、次のリクエストを処理するための容量を解放します。
ダウンロードのタイムアウトを短縮するには:
DOWNLOAD_TIMEOUT = 15
リダイレクトを無効にする¶
リダイレクトの追跡に興味がない限り、リダイレクトを無効にすることを検討してください。広範なクロールを実行する場合、リダイレクトを保存し、後のクロールでサイトを再訪するときにリダイレクトを解決するのが一般的です。これは、クロール・バッチごとにリクエストの数を一定に保つのにも役立ちます。そうしないと、リダイレクト・ループが原因で、クローラーが特定のドメインで多くのリソースを占有する可能性があります。
リダイレクトを無効にするには:
REDIRECT_ENABLED = False
「Ajaxクロール可能なページ」のクロールを有効にします¶
一部のページ(2013年の経験データに基づいて最大1%)は、自身をajaxクロール可能(ajax crawlable)と宣言しています。 これは、通常AJAX経由でのみ利用可能なコンテンツのプレーンHTMLバージョンを提供することを意味します。ページは2つの方法でそれを示すことができます:
URLで
#!
を使用する - これがデフォルトの方法です;特殊なメタ・タグを使用する - この方法は、"main"、"index"ウェブサイトページで使用されます。
Scrapyは (1) を自動的に処理します。そして、 (2) を処理するには、 AjaxCrawlMiddleware を有効にします:
AJAXCRAWL_ENABLED = True
広範なクロールを行う場合、多くの「インデックス」Webページをクロールするのが一般的です。 AjaxCrawlMiddlewareは、それらを正しくクロールするのに役立ちます。 パフォーマンスのオーバーヘッドがあるため、デフォルトではオフになっています。また、集中的なクロール(focused crawls)を有効にすることはあまり意味がありません。
BFO順でクロールする¶
ただし、広範なクロールでは、ページのクロールはページの処理よりも高速になる傾向があります。その結果、未処理の初期リクエストは最終的な深さに達するまでメモリ内に留まり、メモリ使用量が大幅に増加する可能性があります。
メモリを節約するために、代わりに、 BFO順でクロール する。
メモリリークに気を配る¶
BFOの順序でのクロール および 並行処理の低下 に加えて、広範なクロールのメモリ使用量が多い場合、 あなたは メモリリークのデバッグ をするべきです。
指定のTwistedリアクターをインストールする¶
クロールがシステムの機能を超えている場合は、 TWISTED_REACTOR
設定を使用して、指定のTwistedリアクターをインストールしてみてください。