ブロードクロール

Scrapy のデフォルトは, 特定のサイトをクロールするために最適化されています. そのサイトは, 単一の Scrapy スパイダーによって処理されることがよくありますが, これは必須ではありません(たとえば, スローされた任意のサイトを処理するスパイダーがあります).

この「フォーカスクロール」に加えて, ドメインのクロールが完了するまでの間に停止するのではなく, 時間や他の任意の制約によってのみ制限されている(潜在的に無制限の)多数のクロールの一般的なタイプがあります. 実行するリクエストがもうないとき これらは「ブロードクロール」と呼ばれ, 検索エンジンで採用されている一般的なクローラです.

これらは, ブロードクロールでよく見られる共通のプロパティです:

  • 特定のサイトセットではなく, 多くのドメインを無限にクロールする
  • ドメインをクロールする必要はない. そのため, クロールを時間またはクロールされたページ数で制限することは実用的ではない(または不可能)
  • データはしばしば別の段階で後処理されるため, 論理的にはより単純である(多くの抽出規則を持つ非常に複雑なスパイダーとは対照的す)
  • 同時に複数のドメインをクロールするため, 特定のサイトの制約に制限されずに高速なクロール速度を実現できる (各サイトは丁寧さを考慮してゆっくりとクロールされるが, 多くのサイトは並行してクロールされる)

上記のように, Scrapy のデフォルト設定は, ブロードクロールではなく, フォーカスクロールに対して最適化されています. しかし, Scrapy は非同期アーキテクチャであるため, 高速な広範なクロールを実行するのに非常に適しています. このページでは, ブロードクロールを行うために Scrapy を使用する際に留意する必要がある事項と, 効果的なブロードクロールを達成するために調整する Scrapy 設定の具体的な提案をまとめています.

並行性を高める

並行処理は, 並列処理されるリクエストの数です. グローバルごとの制限とドメインごとの制限があります.

Scrapy の既定のグローバル同時実行制限は, 多くの異なるドメインを同時にクロールするのには適していないため, 増やすべきです. どの程度増加させるかは, クローラで使用可能な CPU の量に依存します. 良い出発点は ``100``ですが, 調べる最も良い方法は, いくつかの試行を行い, あなたの Scrapy プロセスがどの CPU に束縛されているかを特定することです. 最適なパフォーマンスを得るには, CPU 使用率が80〜90%の並行処理を選択する必要があります.

グローバルな同時使用を増やすには:

CONCURRENT_REQUESTS = 100

Twisted のIOスレッドプールの最大サイズを増やす

現在のところ, Scrapy は DNS 解決をスレッドプールの使用でブロックします. 並行性レベルが高いと, クロールが遅くなったり, DNS リゾルバのタイムアウトが起こる可能性があります. 解決策としては, DNSクエリを処理するスレッドの数を増やすことです. DNS キューは, 接続の確立と全体的なクロールのスピードアップがされ, 速く処理されます.

スレッドプールの最大サイズを増やすには:

REACTOR_THREADPOOL_MAXSIZE = 20

独自のDNSの設定

複数のクロールプロセスと1つのセントラル 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経由でのみ利用可能なプレーンなHTMLバージョンのコンテンツを提供します. 2つの方法でそれを示すことができます:

  1. URL に #! を使用する - これは一般的な方法です.
  2. 特別なメタタグを使用する - この方法は「メイン」「インデックス」ウェブサイトページで使用されます.

Scrapy は, (1) のみ自動的にハンドリングします. (2) をハンドリングするには AjaxCrawlMiddleware を有効化してください:

AJAXCRAWL_ENABLED = True

ブロードクロールを行う場合, 多くの「インデックス」Webページをクロールするのが一般的です. よって, AjaxCrawlMiddleware は正しくクロールすることができます. フォーマンスのオーバーヘッドがあるため, デフォルトではオフになっています. フォーカスクロールで有効にする意味はあまりありません.