Pythonで自作するスクレイピング基盤の選び方と設計

・ ・ 朝倉 凛

この話題の全体像は ウェブのデータ取得に使う道具を整理し、用途で選び分ける にまとめている。

どの層を自前で持つかを先に決める

自作のスクレイパーは、通信、解析、巡回、操作、保存という層の組み合わせで成り立つ。 通信はHTTPクライアント、解析はHTMLやXMLのパーサ、巡回はキューとスパイダーの制御、操作はブラウザ自動化、保存はファイルやデータベースが担う。 どの層を既存ライブラリに任せ、どの層を自前でまとめるかを最初に決めると、設計の迷いが減る。 規模や更新頻度が変わっても層を差し替えられるように、役割ごとに境界を切っておく。

RequestsとBeautiful Soupで担える範囲

RequestsはPython向けのHTTPライブラリで、資料はHTTP/1.1の送信を簡単にし、クエリやフォームの扱いを自動化すると記している。 資料はKeep-Aliveと接続プールをurllib3で自動化し、セッション、Cookie、SSL検証、プロキシ、タイムアウト、ストリーミングなどを備えるとしている。 資料は公式にPython 3.10以降をサポートすると明記している。

Beautiful SoupはHTMLやXMLからデータを取り出すためのパーサで、資料は木構造を探索し、検索し、変更する手段を提供すると述べている。 資料はBS4の主要機能を例示し、サポート対象はBS4であり、BS3は開発が終了したと記している。 解析は得意だが、ダウンロードや巡回の制御は別の層に任せる前提になる。

連続巡回や出力管理はScrapyで扱う

Scrapyは高速なクローリングとスクレイピングのフレームワークで、資料はウェブサイトの巡回と構造化データの抽出に使えると述べている。 資料はスパイダー、セレクタ、アイテム、アイテムローダー、パイプライン、フィードエクスポート、コマンドラインツールなどの構成要素を挙げる。 資料はチュートリアルとシェルを用意し、対話的に抽出式を試せると案内している。 プロジェクト化して再利用や自動実行を前提にしたいときに、Scrapyは層をまとめて提供する。

JS実行や操作が要る場合のSeleniumの位置づけ

Seleniumはブラウザ自動化のプロジェクトで、資料はW3C WebDriver仕様に基づき主要ブラウザを共通のコードで操作できるとする。 資料は少ない行数でブラウザを起動し、URLに遷移して終了する最小例を示している。 DOMがスクリプトで後から書き換わる場合、HTTPクライアントでは観測できない状態をSeleniumは再現できる。 フォーム送信や無限スクロールのような相互作用が必要なときに候補になる。

層の選び違いが引き起こす実務上の落とし穴

静的に描画されたHTMLなら、RequestsとBeautiful Soupで完結する。 しかし初期HTMLが薄く、JavaScriptがデータを注入するサイトでは、HTTPだけでは目的の要素が現れず、空の抽出結果になりやすい。 逆に全ページをSeleniumで巡回すると、ブラウザ起動のコストが積み上がり、ページ当たりの処理時間とメモリ消費が増える。 連続巡回と出力整形を手作りすると、失敗時の再開や重複排除の実装が散らばり、運用の修正に時間がかかる。

Requestsの接続プールは同一ホストへの往復で効果を出すが、ホストが分散すると再利用は限定的になる。 セッションにCookieを積み上げるとログイン状態を再現できるが、意図せず古い状態を引きずるので、再試行時は新規セッションに切り替える余地を確保する。 ScrapyのセレクタはXPath中心で、CSS選択子より堅い表現が書けるが、DOMの構造変化に敏感になる箇所が出る。 Seleniumは要素の待機を正しく書かないと時間切れや不安定さが増える。

小さく始めて拡張するための実装手順

最初はHTTPクライアントとパーサを薄く組み合わせ、抽出対象とスキーマを固定する。 URLの生成、リクエストのヘッダー、タイムアウト、リトライ、パーサの抽出式を関数に分け、単体で検証できる形に置く。 ページ送りや一覧詳細の往復が増えてきたら、キューと重複検出を加え、ジョブ単位で中断と再開を持たせる。 巡回面を本格化させる必要が出た時点で、Scrapyのスパイダーに移すと、出力と再試行の既成部品をそのまま使える。

動的要件を切り分ける観測のしかた

まずネットワークパネルで初期HTMLと後続のAPI呼び出しの差を観察し、どちらに実体があるかを確かめる。 初期HTMLに全データが載るならHTTPで取る準備が整っているし、後続のJSONで供給されるならHTTPで直接呼ぶ余地が生まれる。 クリックやスクロールでイベントが初めて走り、そこで組み立てられる画面なら、Seleniumで操作を再現する計画に切り替える。 前提の切り分けが済めば、必要な層は自然に決まる。

一次資料から読み取れる前提の違い

Requestsの資料は、人が扱いやすいHTTPクライアントという立ち位置を明示し、接続や認証の面倒を肩代わりするとしている。 Beautiful Soupの資料は、解析そのものに集中し、取得や巡回は別と読むのが適切である。 Scrapyの資料は、巡回と抽出と出力の作法を丸ごと提供する姿勢を取り、プロジェクト運用まで視野に入れている。 Seleniumの資料は、ブラウザを介した相互作用を前提にし、仕様に沿って各ブラウザを同じ形で動かすことを重視している。

移行の目安を言葉にしておく

HTTPとパーサで十分に取れる期間は、そのまま保つのが最も速くて安い。 キュー、再試行、重複排除、エクスポートを自前で積み増し始めたら、Scrapyへ移す判断が成り立つ。 閲覧や操作の要件が混ざったら、Seleniumを限定的に導入し、他の層に影響を広げないように囲い込む。 以上の指針は、一次資料の記述と整合する範囲での見立てである。

出典

  1. Requests: HTTP for Humans — Requests Documentation — Python-Requests (Kenneth Reitz / Open Source) (一次情報)
  2. Scrapy — Official Documentation — Scrapy / Zyte (一次情報)
  3. Beautiful Soup 4 documentation — Beautiful Soup (Leonard Richardson) (一次情報)
  4. Selenium Documentation — SeleniumHQ (一次情報)