「動的サイトはうまく取れない」「ログインが必要なページで詰まる」「大量ページを回したらブロックされた」——Webスクレイピングを自力で実装しようとして、こうした壁にぶつかる方は多いはずです。本記事では2026年8月時点の最新ライブラリ事情を踏まえ、動的サイトのレンダリング・ログイン必須サイトの突破・隠れたAPIの見つけ方・大量取得の設計という4つの実装テクニックを、実際のコードとあわせて解説します。あわせて規約・法令面で必ず押さえるべき注意点も整理しました。
動的サイトのスクレイピング|JS描画コンテンツをどう取得するか
React・Vue等で構築されたサイトはHTMLを直接取得しても中身が空です。ヘッドレスブラウザでJSを実行させてからDOMを読む必要があります。2026年8月時点、主要ツールは以下のバージョンです。
ツール | 最新バージョン | リリース日 | 特徴 |
|---|---|---|---|
Playwright | 1.62.1 | 2026-07-30 | Python/Node両対応。v1.57以降Chromiumではなく Chrome for Testing ビルドを使用 |
Puppeteer | 25.6.0 | 2026-08-11 | Node専用。v23以降デフォルトでChromiumではなくFirefox安定版をDL・使用 |
Scrapy | 2.17.0 | 2026-07-07 | Python 3.10以降が必須に。JS実行が必要な場合はSplash/Playwright連携が必要 |
意外な仕様変更に注意
- Puppeteerはv23.0.0からデフォルトブラウザがChromiumではなくFirefox安定版になっています。従来のヘッドレスChromeは
chrome-headless-shellとして別パッケージに分離されたため、旧来のセットアップ手順のままだと動作が変わる可能性があります。 - Playwrightはv1.57以降、Chromiumの代わりにGoogle公式のChrome for Testingビルドを使うようになりました。テスト環境の再現性は上がりますが、既存のDockerイメージやCIの依存関係定義は見直しが必要です。
実装例(Playwright Python)
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://example.com/products", wait_until="networkidle")
page.wait_for_selector(".product-card")
items = page.query_selector_all(".product-card")
for item in items:
title = item.query_selector(".title").inner_text()
price = item.query_selector(".price").inner_text()
print(title, price)
browser.close()
wait_for_selectorで要素の出現を待たずにgoto直後に取得しようとすると、レンダリング未完了で空データになる失敗が最も多いパターンです。無限スクロールのサイトではpage.mouse.wheel()でスクロールイベントを発火させつつ、追加読み込み後の要素数変化を監視するループが必要になります。
ログイン必須サイトのセッション管理
Cookie・ストレージステートの再利用
毎回ログインフォームを操作すると速度が落ち、reCAPTCHA等の追加認証がトリガーされるリスクも高まります。Playwrightなら一度ログインした状態をstorage_stateとして保存し、以降のセッションで再利用するのが定石です。
# 初回のみ:ログイン後に状態を保存
context = browser.new_context()
page = context.new_page()
page.goto("https://example.com/login")
page.fill("#email", "user@example.com")
page.fill("#password", "password")
page.click("#login-button")
page.wait_for_url("**/dashboard")
context.storage_state(path="auth_state.json")
# 2回目以降:保存済み状態を読み込むだけでログイン済み扱い
context = browser.new_context(storage_state="auth_state.json")
2段階認証・CAPTCHAの限界を理解する
SMS認証や画像認証を突破する実装は、対象サイトの規約違反になる可能性が高く、技術的にも不安定です。ここは無理に自動化せず、「初回ログインだけ人手で行いセッションを使い回す」設計にとどめるのが現実的な落としどころです。この判断を誤ると、ブロックされるだけでなくアカウント停止につながることもあります。
隠れたAPIの見つけ方|DevTools Networkタブの使い方
HTMLをパースするより先に、対象サイトが内部で叩いているJSON APIを探す方が圧倒的に安定した実装になります。手順は次の通りです。
- ブラウザのDevToolsを開き「Network」タブで「Fetch/XHR」だけに絞り込む
- 対象ページで検索・ページ送り・フィルタ操作を行い、発生したリクエストを確認する
- レスポンスがJSONを返しているエンドポイントを特定し、リクエストヘッダー(認証トークン・Referer等)を控える
- Pythonの
requestsで同じヘッダーを付けて直接叩けるか検証する
import requests
headers = {
"User-Agent": "Mozilla/5.0 ...",
"X-Requested-With": "XMLHttpRequest",
"Referer": "https://example.com/products",
}
res = requests.get("https://example.com/api/v2/products?page=1", headers=headers)
data = res.json()
この方法が使えればブラウザ起動が不要になり、速度・安定性ともに数倍〜数十倍改善します。ただし内部APIは予告なく仕様変更されるため、レスポンス構造の変化を検知するテストを組み込んでおくと保守が楽になります。こうしたAPI仕様の裏取りや、恒常的な監視・アラート化の仕組みづくりは、Claude API 実装ガイド|Pythonで作る業務自動化の実践コードで紹介しているようなAIエージェントに監視スクリプト自体を書かせる方法とも相性がよく、変更検知〜通知までを自動化できます。
大量取得の設計|レート制御・プロキシ・クラウド分散
ノーコード・AI系ツールとの使い分け
2026年時点でThunderbit・Kadoa・Browse AI・ScrapeStormのようなAI搭載ツールが自動検出やレイアウト変更への適応を謳っていますが、現場の評価では「定常的なレイアウト変更には強いが、大規模なサイト再設計には自動適応が保証されない」という限界も指摘されています。定型作業はノーコードツール、規模拡張とブロック回避はAPI型サービス、細かい制御が必要な場面はPythonライブラリ、という役割分担が2026年の現場で定着しています。
サービス | 料金目安 | 特徴 |
|---|---|---|
Octoparse | Standard 月額69ドル〜(個人向けは月額119円〜との情報も) | AI自動検出・視覚的ワークフロー・日本語サポート |
ParseHub | 月額189ドル〜 | 無料プランあり |
Browse AI | 無料(月50クレジット)/Personal月19ドル〜 | クレジット制。高容量タスクではコスト増に注意 |
ScraperAPI | 7日間無料トライアル/月額49ドル〜 | プロキシ・レンダリング込みのAPI型 |
80legs | 無料〜299ドル(Enterpriseは要問合せ) | クロール規模に応じた段階プラン |
ShtockData | 要問合せ | 日本企業向け、導入・長期運用支援に強み |
並列化とレート制御の実装
数千〜数万ページ規模になると、単純にリクエストを並列化するだけでは対象サーバーに負荷をかけすぎたり、即座にブロックされたりします。asyncioのセマフォで同時実行数を絞り、リクエスト間隔にジッター(ランダムな待機時間)を入れるのが基本です。
import asyncio, random
import httpx
sem = asyncio.Semaphore(5) # 同時実行数を制限
async def fetch(client, url):
async with sem:
await asyncio.sleep(random.uniform(0.5, 1.5)) # ジッター
res = await client.get(url)
return res.json()
async def main(urls):
async with httpx.AsyncClient(timeout=20) as client:
return await asyncio.gather(*[fetch(client, u) for u in urls])
サーバーレス構成(AWS Lambda・Cloud Run等)でスクレイパーを分散実行するクラウド基盤の活用も、大規模案件では標準的な選択肢になりつつあります。自前でVPSを常時起動しておくより、実行時だけ課金されるぶんインフラコストを抑えやすいのが利点です。
規約・法令面の注意とアンチボット対策の現実
- 利用規約(ToS)の事前確認は必須。スクレイピング自体を明示的に禁止しているサイトも多く、規約違反はアカウント停止や損害賠償請求のリスクにつながります。
- 著作権・個人情報保護法にも留意。取得したデータの保存・再配布方法によっては別の法的リスクが生じます。
- Cloudflare・DataDome等のアンチボット対策は年々強化されており、プロキシローテーションやヘッドレスブラウザのフィンガープリント対策が引き続き必要です。ただし対策を掻い潜る実装は相手サイトとのいたちごっこになりやすく、規約違反すれすれの手法に頼るほど保守コストも跳ね上がります。
- robots.txtの確認と、可能な限り公式APIの利用を優先する姿勢が、長期的に安定運用するための前提になります。
ここまで見てきた通り、動的サイトのレンダリング、セッション管理、隠れたAPIの調査、大量取得時のインフラ設計、そして規約・法令チェックまで、スクレイピングは「動くコードを書く」だけでは終わりません。ライブラリのバージョンアップに追従し続ける保守コストも無視できず、片手間で運用するには重い作業です。AIを活用した業務自動化全般の勘所はAI×業務自動化の受託事例|生成AI導入で案件単価を上げる方法でも紹介しているので、あわせてご覧ください。
この記事に関連するアイテム
実際に使うものを選ぶ際の参考にどうぞ。
※ 本サイトはAmazonアソシエイト・プログラムの参加者です。紹介リンクを経由してご購入いただいた場合、手数料を受け取ることがあります。
まとめ
2026年8月時点、Playwright(1.62.1)・Puppeteer(25.6.0)・Scrapy(2.17.0)はいずれも活発に更新が続いており、デフォルトブラウザの変更など仕様変化への追従も必要です。動的サイトのレンダリング、ログインセッションの再利用、隠れたAPIの発見、大量取得時のレート制御とクラウド分散、そして規約・法令の確認——どれか一つでも欠けると、ブロックや法的リスクにつながります。自力での実装・運用が負担に感じる場合は、専門家への外注も有効な選択肢です。 業務自動化・スクレイピングの導入をご検討の方はnashiまでお問い合わせください。https://nashi-portfolio.netlify.app