【要約】落ちないPythonスクレイパーの設計 ── 3段フォールバック・指数バックオフ・文字化け対策の実務 [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
データ収集システムの運用者が、作成直後は動作するものの、時間の経過とともにスクレイパーが停止する問題に直面している。これは取得ロジックのバグではなく、外部環境の変化が原因である。具体的には以下の課題が挙げられる。
- ・ネットワークの瞬断や502/503エラーによる一時的な失敗。
- ・UAやアクセス頻度によるアクセス制御の強化に伴うブロック。
- ・JavaScriptによる動的レンダリングへの移行によるデータ取得不能。
- ・EUC-JP等の古い文字コードによる文字化けの発生。
// Approach
取得手段を単一のライブラリに依存させず、コストと耐障害性のバランスを考慮した多層構造を採用する。取得を「層」として定義し、軽い手段から順に試行する設計を行う。
- ・3段フォールバック:httpx(軽量)→ アンチbot対応Fetcher → Playwright(重厚)の順で試行する。
- ・賢いリトライ:403/404は即断念し、タイムアウト等は指数バックオフを用いて待機する。
- ・文字コード対策:HTMLヘッダからcharsetを抽出し、動的にデコードを行う。
- ・Graceful Degradation:重い依存関係をtry/except ImportErrorでオプション化する。
- ・レート制限:リクエスト間に最低間隔を設けることで、相手サーバーへの負荷を抑制する。
// Result
設計を層(Layer)として抽象化することで、運用安定性とコスト効率の両立を実現している。これにより、以下の成果が得られる。
- ・99%のページを軽量なhttpxで処理し、計算リソースと実行コストを最小化する。
- ・基底クラスへ耐障害性を集約し、個別スクレイパーの開発負荷を軽減する。
- ・数ヶ月間のノンストップ稼働を実現し、継続的なデータ収集を可能にする。
Senior Engineer Insight
> 実戦的な設計である。特に「エラーの性質によるリトライの切り分け」と「依存関係の遅延インポート」は、大規模運用でのクラッシュを防ぐ要諦だ。フォールバックは堅牢性を高めるが、多段にわたるとレイテンシが増大する。対象サイトの特性に応じ、最初からどの段を使用するかを選択できる柔軟性も重要だ。また、レート制限の実装は、法的・倫理的なリスク回避の観点からも必須である。