Webスクレイピングの実務ガイド|法規制・robots.txt・ToS・個人情報の境界線
スクレイピングの可否は「技術的に取得できるか」ではなく、robots.txt・利用規約(ToS)・著作権・個人情報保護法の4軸で決まる。公式APIを最優先し、取得は識別可能なUser-Agent・低頻度・最小限のデータで行う。429・CAPTCHA・WAF遮断は「止まれ」の信号であり、技術的回避の前に Anti-Bot対策記事 で防御の意味を理解したうえで、グレーゾーンは実装前に法務へ相談する。
スクレイピングと法務の全体像
Webスクレイピングとは、HTTPでHTML・JSON・RSSなどを取得し、必要なフィールドを抽出・正規化・保存する一連の処理を指す。価格監視、SEO分析、研究用データセット、競合調査、機械学習の教師データ作成など、ビジネス上の需要は大きい。
一方で、取得先のサーバー負荷、サイト運営者の意図に反する利用、著作物の無断複製、個人のプライバシー侵害といったリスクも常に付きまとう。「公開ページだから自由」という前提は成り立たない。エンジニアが最初に押さえるべき論点は次の4つだ。
| 論点 | 主な問い | 典型的なリスク |
|---|---|---|
| robots.txt | クロール禁止パスはどこか | ToS違反・信頼関係の毀損・ブロック |
| 利用規約(ToS) | 自動取得・再配布は許可されているか | 差止・損害賠償・アカウント停止 |
| 著作権・不正競争 | 複製・翻案・公衆送信に当たるか | 侵害警告・訴訟 |
| 個人情報保護法 | 個人データの取得・利用・第三者提供は適法か | 行政指導・罰則・信用失墜 |
技術チームは「実装できるか」より先に「何を・なぜ・どこまで・いつまで」を1枚の設計メモに書き出す。後から「知らなかった」では済まされない場面が多い。
法務と技術の役割分担
| 担当 | 判断すること | 判断しないこと |
|---|---|---|
| エンジニア | robots.txt パース、レート制限、429停止、取得フィールドの最小化 | 個別案件の刑事・民事責任の最終判断 |
| 法務・コンプライアンス | ToS解釈、APPI適用、契約・ライセンス交渉 | DOMセレクタのメンテナンス |
| プロダクト | 取得の事業必要性、API vs スクレイピングのコスト | WAF突破の実装方針 |
以下はエンジニア向けの実務整理であり、個別案件の法的判断は弁護士・社内法務に委ねること。国・州・業界ごとに法制度は異なる。
robots.txtの読み方とパース実装
robots.txt はサイトルート(https://example.com/robots.txt)に置かれるプレーンテキストで、クローラーへのクロール方針を伝える仕組みだ。RFC 9309 で標準化されており、Googlebot など主要クローラーはこれを尊重する。
ただし重要なのは、robots.txt は法的拘束力そのものではない点だ。Disallow されたURLにアクセスしても自動的に刑事罰が課されるわけではない。逆に Allow されていても、ToS・著作権・個人情報の問題は残る。スクレイパー側は「マナー」として尊重し、禁止パスへは入らない実装を標準とする。
記述例と意味
例1:管理画面とAPIの拒否
User-agent: *
Disallow: /admin/
Disallow: /api/private/
Allow: /api/public/docs/
Sitemap: https://example.com/sitemap.xml
User-agent: *— すべてのクローラーが対象Disallow: /admin/—/admin/以下はクロールしないでほしいAllow:— より具体的なパスで Disallow を上書き(/api/public/docs/は許可)Sitemap:— サイトマップの場所(クロール可否とは別のヒント)
例2:特定ボットだけ全面拒否
User-agent: GPTBot
Disallow: /
User-agent: *
Disallow: /checkout/
Crawl-delay: 2
- ボット名ごとに方針を分けられる(
GPTBot、Googlebotなど) Crawl-delayは非標準だが、一部クローラーがリクエスト間隔の目安として参照する
例3:ワイルドカードとクエリ文字列(Google拡張)
User-agent: *
Disallow: /*?*sessionid=
Disallow: /search?
Allow: /search?type=product$
パス末尾の $ は「ここで終わる」という Google 独自のマッチ。実装ライブラリによって解釈が異なるため、本番前に対象サイトの robots.txt を実際にパースしてテストする。
Python:標準ライブラリでパース
from urllib.parse import urlparse
from urllib.robotparser import RobotFileParser
def can_fetch(url: str, user_agent: str = "MyResearchBot/1.0") -> bool:
parsed = urlparse(url)
robots_url = f"{parsed.scheme}://{parsed.netloc}/robots.txt"
rp = RobotFileParser()
rp.set_url(robots_url)
rp.read() # ネットワーク取得。キャッシュは自前で層を足す
return rp.can_fetch(user_agent, url)
# 使用例
target = "https://example.com/products/123"
if can_fetch(target):
print("取得候補")
else:
print("robots.txt により取得をスキップ")
RobotFileParser はシンプルだが、キャッシュTTL・リダイレクト・HTTPエラー時の扱いは自前実装が必要だ。robots.txt が 5xx を返した場合の方針(取得中止 vs 制限なしとみなす)はチームで決めておく。
Python:TTL付きキャッシュと取得前チェック
import time
from urllib.parse import urlparse
from urllib.robotparser import RobotFileParser
class RobotsCache:
"""ホストごとに RobotFileParser をキャッシュ(TTL簡略版)"""
def __init__(self, ttl_seconds: float = 3600):
self._cache: dict[str, tuple[RobotFileParser, float]] = {}
self._ttl = ttl_seconds
def allowed(self, url: str, ua: str) -> bool:
host = urlparse(url).netloc
now = time.monotonic()
entry = self._cache.get(host)
if entry is None or now - entry[1] > self._ttl:
rp = RobotFileParser()
scheme = urlparse(url).scheme or "https"
rp.set_url(f"{scheme}://{host}/robots.txt")
try:
rp.read()
except OSError:
return False # 読めないときは保守的に拒否
self._cache[host] = (rp, now)
entry = self._cache[host]
return entry[0].can_fetch(ua, url)
Node.js:robots-parser の例
import robotsParser from "robots-parser";
import fetch from "node-fetch";
async function isAllowed(url, userAgent = "MyResearchBot/1.0") {
const { origin } = new URL(url);
const res = await fetch(`${origin}/robots.txt`);
const body = await res.text();
const robots = robotsParser(`${origin}/robots.txt`, body);
return robots.isAllowed(url, userAgent) ?? true;
}
robots.txt パースで落としがちな罠
- User-agent の不一致 —
MyBot/1.0でcan_fetchしているのに、実際の HTTP リクエストはpython-requests/2.xだと、運営者から見て「別ボット」になる - Disallow パスの部分一致 —
/privateが/private-infoにもマッチするかはパーサー実装依存 - robots.txt 未更新 — 本番デプロイ後に Disallow が追加されても、キャッシュTTLが長いと禁止パスへアクセスし続ける
- サブドメイン単位 —
www.example.comとapi.example.comは別ファイル。ホストごとに取得が必要
Disallow は「クロールしてほしくない」という申し出であり、認証なしの秘密保持手段ではない。/secret/ を Disallow にしてもURLが漏れれば誰でもアクセスできる。サイト運営者は robots.txt に頼らず認証・noindex・WAFで守るべきだ。
利用規約(ToS)違反が問題になるケース
多くのWebサービスは利用規約で自動アクセス・スクレイピング・データの再配布・商用利用を明示的に禁止している。「ブラウザで見える=利用規約上も許可されている」ではない。ログイン後のダッシュボード、検索結果、レビュー一覧も、ToS上は自動取得が禁じられていることがほとんんだ。
典型的なToS条項
- ロボット・スパイダー・クローラーによるアクセス禁止
- コンテンツの複製・改変・再配布・派生データセットの販売禁止
- APIキーの共有禁止、レート制限の迂回禁止
- CAPTCHA・技術的保護手段の回避禁止
- 競合サービス・モデル学習への利用禁止
違反が直ちに刑事事件になるとは限らないが、民事上の損害賠償・差止命令・アカウント永久停止・IPブロックは現実的な制裁だ。B2Bでデータを商品化する場合、契約・ライセンス条項の精査は必須になる。
ToS違反の具体例(パターン別)
| パターン | 典型的な行為 | 想定される制裁 |
|---|---|---|
| 明示禁止の迂回 | ToSで「自動取得禁止」とあるECサイトの価格を毎時クロール | アカウント停止・IPブロック・損害賠償請求 |
| API迂回 | 無料APIの1日1000件制限を、HTMLスクレイピングで突破 | ToS違反・契約解除・差止 |
| CAPTCHA突破 | reCAPTCHA表示後、突破サービスで継続取得 | ToS + CAPTCHA提供者ToS違反。CFAA/不正アクセスの論点も |
| Cookie流用 | ログインセッションCookieをスクリプトに埋め込み会員限定データ取得 | アカウント規約違反・不正アクセス |
| 再配布・学習利用 | レビュー全文をCSV化し社外販売・LLM学習に提供 | 著作権・ToS・APPIの複合リスク |
| 競合分析 | 転職サイトの求人・年収データを社内DBに蓄積 | 不正競争・ToS違反で警告・訴訟に至った報道例あり |
海外・国内で議論になった事例(整理)
| 事例・論点 | 概要 | エンジニアへの示唆 |
|---|---|---|
| hiQ Labs v. LinkedIn(米国) | 公開プロフィールのスクレイピングを LinkedIn が制止。CFAA(不正アクセス法)適用を巡る争い | 「公開」と「ToS上の自動取得禁止」は別。サイト側は技術・契約の両面で防御する |
| Meta v. Bright Data(米国) | 公開データの取得を巡るToS・CFAA論点 | 公開ページでもToS・技術的防御との組み合わせで争点化 |
| Ryanair 等(EU) | 航空券価格のスクレイピングを ToS・DB権で争った判例群 | 価格・スケジュールも「データベースの抽出」で問題になりうる |
| 国内:転職・求人・口コミサイト | 利用規約違反・不正競争で警告・訴訟に至った報道例あり | 競合分析目的でも「社内利用」は免責にならない |
| SNS・マーケットプレイス | ボット検知・API制限・法的通知によるアカウント停止が日常化 | API・パートナープログラムが用意されているサービスほど、迂回はリスクが高い |
技術的に取得できた事実は、ToS違反の抗弁にはならない。「止められなかったから許された」ではなく「許可された範囲だけ取る」のがプロの前提だ。
米国CFAAと日本法の比較:不正アクセスの線引き
越境サービスや米国サーバー上のデータを扱う案件では、米国 Computer Fraud and Abuse Act(CFAA) が議論に上がる。日本の不正アクセス禁止法と「似ているが同じではない」点を理解しておく。
制度の概要
| 観点 | 米国 CFAA(18 U.S.C. § 1030) | 日本 不正アクセス禁止法 |
|---|---|---|
| 対象 | コンピュータ(広義)への不正アクセス・超過権限利用 | アクセス制御機能を突破した行為 |
| 「公開」の扱い | hiQ v. LinkedIn 等で「ToS違反=CFAA」論点が争われた(2022年最高裁は一定限界を示唆) | 公開ページの polite 取得と、CAPTCHA/WAF突破は別評価 |
| 典型例 | 認証突破、権限外データ取得、内部API総当たり | CAPTCHA回避、漏洩認証情報でのログイン、保護機能の意図的回避 |
| 民事・刑事 | 刑事罰+民事損害賠償 | 刑事罰(不正アクセス罪等)+損害賠償請求 |
| ToS違反単独 | 判例上、ToS違反だけでは不十分という方向性も | ToS違反は主に民事(契約)・別法令で評価 |
エンジニア向けの線引き表
| 行為 | CFAA / 日本法上のリスク感(一般論・個別相談要) |
|---|---|
| 公開ページを低頻度・robots遵守で取得 | CFAA: 争点になりにくい方向。日本: ToS・著作権で別評価。429なら停止 |
| ToS禁止サイトをWAF突破で取得 | CFAA: 超過アクセス論点。日本: 不正アクセス・ToS民事リスク |
| CAPTCHA突破サービス利用 | 技術的保護回避。CFAA・不正アクセス・ToSの複合 |
| 漏洩パスワードでログイン | 典型的な不正アクセス(日米とも高リスク) |
| 内部API(/api/internal)を総当たり | アクセス制御突破。刑事・民事とも高リスク |
| 429無視・IPローテーションで継続 | CFAA直接よりToS・損害賠償・永久ブロックが現実的 |
hiQ Labs v. LinkedIn から学ぶこと
LinkedIn は hiQ Labs の公開プロフィール取得を CFAA 違反として制止しようとした。争いは「ToSで禁止された公開データへのアクセスが CFAA の『不正アクセス』に当たるか」が焦点だった。2022年米最高裁は、権限内アクセスの定義について一定の限界を示し、ToS違反だけを自動的に CFAA 犯罪とみなす道は狭まった方向と言われる。
ただし「CFAAの心配が減った=スクレイピング自由」ではない。LinkedIn は ToS・差止・技術的防御(Anti-Bot)で対抗し続けている。エンジニアは CFAA を知ったうえで、ToS・robots.txt・429停止を実務の第一防衛線に据えるべきだ。
日本の個人情報保護法(APPI)とスクレイピング
日本の個人情報保護法(APPI)は、生存する個人に関する情報で、特定の個人を識別できるもの(個人情報)、および個人情報データベース等を構成する個人データ・保有個人データを規律する。2022年改正以降、漏えい報告義務や仮名加工・匿名加工の枠組みも実務に直結する。
スクレイピングで扱いやすいデータ例
- SNSの表示名・プロフィール文・投稿内容・フォロー関係
- 掲示板のハンドルネーム・投稿日時・IPが推測できるログ
- レビューサイトのユーザーID・購入履歴に紐づくコメント
- 不動産・求人サイトに掲載された担当者名・電話番号
APPI上の実務ポイント
1. 利用目的の特定と公表 — 個人データを事業で取得・利用するなら、何のために使うかを特定し、原則として本人が知り得る状態(プライバシーポリシー等)に置く。社内分析だけでも、法人として取り扱うなら該当しうる。
2. 要配慮個人情報 — 人種、信条、病歴、犯罪経歴などは原則として取得・利用・第三者提供に同意が必要。プロフィールや投稿から推測できる場合も、設計段階で除外・マスキングを検討する。
3. 第三者提供・共同利用 — スクレイプした個人データをそのまま別会社に渡す、クラウド上の学習用に再配布するなどは第三者提供に当たりうる。契約・匿名化・統計化の要否を法務と確認する。
4. 仮名加工情報・匿名加工情報 — 一定の手続を踏めば、分析・AI学習に使いやすい形にできるが、復元可能性・再識別リスクの評価が必要。「ハッシュしたから個人情報ではない」は単純には成り立たない。
5. 国外移転 — 海外サーバーへ保存する、OpenAI等の国外APIに渡す場合は、外国にある第三者への提供のルール(同意・十分な体制等)を確認する。
6. 漏えい報告 — 個人データの漏えい等が一定規模に達すると、個人情報保護委員会への報告と本人通知が義務化されている。
個人情報を含みうるかの判定フロー
取得フィールド一覧を書き出し、氏名・メール・電話・住所・ユーザーID・位置情報・顔画像の有無を確認する
他のデータと組み合わせて特定個人を識別できるか(リンク可能性)を評価する
利用目的・保存期間・削除手順をドキュメント化し、不要フィールドは取得段階で落とす
第三者提供・国外移転・AI学習利用の有無を法務とすり合わせる
仮名化・匿名化が必要なら、復元攻撃を想定した設計レビューを行う
インターネット上に表示されていても、投稿者の著作権・肖像権・プライバシーは残る。研究・AI学習向けデータセットでも、近年はガイドラインと規制が強まっている。必要最小限・匿名化・保存期限をコードとポリシーの両方で実装する。
著作権・不正競争防止法
著作権法
Webページ上の文章、写真、イラスト、動画、レイアウト、場合によってはデータベースの構成(データベースの著作物)も著作権で保護される。スクレイピング結果をそのまま再公開・販売・学習データとして再配布すると、複製権・翻案権・公衆送信権の侵害が問題になる。
一方、事実のみ(商品価格、気温、株価の数値、営業時間)や、独自の集計・ランキングロジックは別評価になりうる。境界は案件依存のため、生HTMLの丸ごと保存は避け、必要最小限のフィールドを正規化して保存する設計が無難だ。
不正競争防止法
営業秘密や、相当の施行を伴う顧客リストなど、限定公開・技術的保護されたデータを無断取得・利用すると、不正競争防止法(第2条第1項各号)の問題になりうる。ログイン後のみ見える卸価格、会員限定の在庫情報は特に注意。
保存・利用の実務指針
- 生HTMLアーカイブ — 監査・デバッグ用に短期保持するならアクセス制限。長期一括保存は著作権リスク
- 正規化フィールド — 価格・SKU・在庫数など事実データに限定
- 出典・取得日時 — 後追い説明と削除要求への対応用にメタデータを残す
- 再配布 — 社外提供・API公開前に法務レビュー
公式APIとスクレイピングの意思決定マトリクス
同じデータでも、公式API・データフィード・パートナープログラムがあれば、そちらを第一選択にする。HTMLスクレイピングはDOM変更に弱く、メンテナンスコストも高い。
| 観点 | HTMLスクレイピング | 公式API |
|---|---|---|
| ToS・法務リスク | 多くのサイトで明示禁止。グレーゾーンを踏みやすい | 利用条件が明文化。キー発行で契約関係が成立しやすい |
| 安定性 | CSSセレクタ・DOM構造変更で即壊れる | スキーマ変更が changelog で通知されることが多い |
| レート制限 | 暗黙の上限。ブロックされてから気づく | ヘッダー・プランで上限が明示(429 + Retry-After) |
| コスト | インフラ・保守人件費は見えにくい | 従量課金・プラン料金が発生しうる |
| 取得範囲 | ページに出ていれば取れるが、それが許可されているとは限らない | 公開フィールドに限定されることが多い |
| 認証・個人情報 | セッションCookie流用はアカウント規約違反になりやすい | OAuth・スコープで最小権限を設計しやすい |
意思決定の目安
| 状況 | 推奨 |
|---|---|
| 公式APIがあり、必要フィールドが揃う | APIのみ |
| APIはあるが不足フィールドがある | データ提供の問い合わせ → ダメなら取得範囲を再設計 |
| APIはないが robots.txt・ToS が許容的 | 低頻度の polite スクレイピング + 連絡先付き UA |
| ToS が自動取得を明示禁止 | スクレイピングしない(契約・ライセンス交渉) |
| ログイン必須・CAPTCHA・会員限定 | 公式連携・OAuth・パートナーAPI を探す |
| 個人情報が大量に含まれる | 取得自体を見直す(APPI・同意の要否) |
「APIがあるのにスクレイピングで迂回する」は、短期的には早くても、中長期ではブロック・訴訟・再実装コストのほうが大きくなりやすい。
倫理的判断マトリクス:取得前に立ち止まる
法務レビュー前のエンジニア自己点検用に、2軸で「進む・止まる」を切り分ける。X軸は許可の明示度、Y軸はデータの敏感性。
マトリクス(一般論)
| 許可が明示的(ToS OK / データライセンス / 書面許諾) | グレーゾーン(ToS 無記載・robots 許容) | 明示的禁止(ToS禁止 / Disallow / CAPTCHA) | |
|---|---|---|---|
| 公開の非個人データ(価格・天気・統計) | ✅ 進める(API優先・polite実装) | ⚠️ 法務確認後・低頻度・停止可能設計 | ❌ 止める(交渉か代替データ) |
| 公開だが個人に紐づく(レビュー・SNS・プロフィール) | ⚠️ APPI・目的限定・最小化 | ❌ 原則止める(法務必須) | ❌ 止める |
| 認証・会員限定 | ⚠️ OAuth/API・契約スコープ内のみ | ❌ 止める | ❌ 止める(不正アクセスリスク) |
| 競合・学習・再配布用途 | ⚠️ ライセンス条項を精読 | ❌ 止める | ❌ 止める |
セルごとの推奨アクション
✅ 進める — 公式APIまたは polite スクレイピング。User-Agent・robots・レート制限・ログを実装。429で自動停止。
⚠️ 法務確認 — 設計書(目的・フィールド・保存期間)を1枚にまとめ、止まれる実装(feature flag)を入れてから PoC。
❌ 止める — 技術的回避(WAF・CAPTCHA・プロキシローテ)に進まない。代替API・手動サンプル・第三者データベースを検討。
倫理の核心原則
倫理とは「バレないようにする」ことではない。相手の意図・負荷・利用規約を尊重し、疑義があれば取得を止められる体制を持つことだ。429・403・CAPTCHAは、サイト側が送る停止信号として解釈する(技術的詳細は Anti-Bot対策記事 参照)。
ポライトスクレイピング:レート制限の実装
相手サーバーへ短時間に大量リクエストを送ると、DoSに近い負荷を与える。倫理的にも、ToS・損害賠償の文脈で問題になりうる。実装では次をセットで入れる。
- 識別可能な User-Agent —
MyBot/1.0 (+https://example.com/bot-info)のように連絡先URL付き - ホストごとの最小間隔 — 1秒以上、または robots.txt の
Crawl-delay遵守 - 並列数の上限 — 同一ホストへ同時接続は2〜3本程度
- 指数バックオフ — 429 / 503 応答時は待機を倍増
- キャッシュ — ETag /
If-Modified-Sinceで再取得を避ける - ピーク時間の回避 — 夜間バッチ・ジョブキューで分散
Python:PoliteFetcher(robots + レート制限 + バックオフ)
import random
import time
from collections import defaultdict
from dataclasses import dataclass, field
from typing import Optional
from urllib.parse import urlparse
import requests
from urllib.robotparser import RobotFileParser
USER_AGENT = "KawaResearchBot/1.0 (+https://kawa.dev/bot; [email protected])"
@dataclass
class PoliteFetcher:
min_interval: float = 1.5
max_retries: int = 5
_last_request: dict[str, float] = field(default_factory=lambda: defaultdict(float))
_robots: dict[str, RobotFileParser] = field(default_factory=dict)
session: requests.Session = field(default_factory=requests.Session)
def __post_init__(self) -> None:
self.session.headers["User-Agent"] = USER_AGENT
def _host(self, url: str) -> str:
return urlparse(url).netloc
def _ensure_robots(self, url: str) -> RobotFileParser:
host = self._host(url)
if host not in self._robots:
rp = RobotFileParser()
scheme = urlparse(url).scheme or "https"
rp.set_url(f"{scheme}://{host}/robots.txt")
try:
rp.read()
except OSError:
pass
self._robots[host] = rp
return self._robots[host]
def _wait_polite(self, url: str) -> None:
host = self._host(url)
elapsed = time.monotonic() - self._last_request[host]
jitter = random.uniform(0.2, 0.8)
delay = self.min_interval + jitter - elapsed
if delay > 0:
time.sleep(delay)
def get(self, url: str) -> Optional[str]:
rp = self._ensure_robots(url)
if not rp.can_fetch(USER_AGENT, url):
return None
for attempt in range(self.max_retries):
self._wait_polite(url)
self._last_request[self._host(url)] = time.monotonic()
resp = self.session.get(url, timeout=30)
if resp.status_code == 429:
retry_after = float(resp.headers.get("Retry-After", 2 ** attempt))
time.sleep(retry_after + random.uniform(0, 1))
continue
if resp.status_code in (403, 503):
# WAF / Anti-Bot の可能性。継続より停止を優先
return None
if resp.status_code in (500, 502, 504):
time.sleep(min(60, (2 ** attempt) + random.uniform(0, 1)))
continue
resp.raise_for_status()
return resp.text
return None
セマフォで並列数を抑える例
import asyncio
import aiohttp
HOST_SEMAPHORES: dict[str, asyncio.Semaphore] = {}
def semaphore_for(url: str, limit: int = 2) -> asyncio.Semaphore:
from urllib.parse import urlparse
host = urlparse(url).netloc
if host not in HOST_SEMAPHORES:
HOST_SEMAPHORES[host] = asyncio.Semaphore(limit)
return HOST_SEMAPHORES[host]
async def fetch_one(session: aiohttp.ClientSession, url: str) -> str:
async with semaphore_for(url, limit=2):
await asyncio.sleep(1.2)
async with session.get(url, headers={"User-Agent": USER_AGENT}) as resp:
if resp.status in (403, 429):
raise RuntimeError(f"Blocked or rate limited: {url}")
resp.raise_for_status()
return await resp.text()
429 が返ってきたら間隔を広げる・並列を下げる・そのホストの取得を一時停止する。相手の Retry-After ヘッダーは最優先で尊重する。403 が Cloudflare の cf-ray 付きで返る場合は、突破より Anti-Bot記事 のフローに従い停止・問い合わせを検討する。
Anti-Bot対策との関係:技術記事との併読
法務・倫理と技術は切り離せない。サイト側の防御(WAF、Cloudflare Bot Fight Mode、フィンガープリント、CAPTCHA)を理解しないと、「403だからToS違反を突破しよう」という誤った判断に至りやすい。
記事間の読み分け
| 本記事(法的・倫理) | Anti-Bot対策記事 |
|---|---|
| robots.txt / ToS / 著作権の解釈 | WAF / Cloudflare / フィンガープリントの仕組み |
| 規約違反時の法的リスク | 429・403の技術的対応 |
| 個人情報・再配布のコンプライアンス | レート制限・CAPTCHAの実装と挙動 |
| 迷ったときの法務相談フロー | 防御に抵触しない取得の作法 |
防御シグナルと法的含意
| シグナル | 技術的意味(Anti-Bot記事) | 法的・倫理的含意(本記事) |
|---|---|---|
| 429 + Retry-After | レート超過。待機・頻度低下 | 継続はToS・損害賠償リスク。尊重して停止判断 |
| 403 + cf-ray | Cloudflare WAF / Bot Management | 自動取得拒否。突破はToS・不正アクセス論点 |
| CAPTCHA | 人間確認。HTTPクライアントでは不可 | 停止信号。突破サービスは非推奨 |
| 503 + Set-Cookie | JSチャレンジ前段 | サイト意図に反する迂回は避ける |
Anti-Botの「回避テクニック」を学ぶ目的は、防御を理解し、許可された範囲で持続可能なデータ取得を設計することにある。防御を破るための手順書ではない。
倫理的チェックリストと社内ガバナンス
技術的コンプライアンスと倫理はセットだ。次のチェックリストを、プロジェクト着手時・四半期ごと・ToS改定時に見直す。
対象URL・取得フィールド・利用目的・保存期間・削除手順を1枚の設計書にまとめたか
robots.txt をパースし、禁止パス・Crawl-delay をコードで尊重しているか
利用規約で自動取得・再配布・商用利用・AI学習が禁止されていないか確認したか
同等データの公式API・データライセンス・問い合わせ窓口を調査したか
User-Agent にボット名と連絡先URL(またはメール)を明記したか
レート制限・並列上限・バックオフ・ログ・キャッシュを実装したか
個人情報・要配慮個人情報が含まれないか、含む場合はAPPI上の措置を法務と合意したか
生HTMLの一括保存ではなく、必要最小限の正規化データだけを保持しているか
CAPTCHA・ログイン壁・技術的保護手段を迂回する実装をしていないか
429・403検知時に自動停止するサーキットブレーカーを実装したか
ステージングで少量取得し、DOM変更・HTTPエラー・ブロックの監視アラートを設定したか
本番運用後も ToS・robots.txt の変更を定期チェックする担当を決めたか
社内で決めておくとよいポリシー
- 禁止リスト — 転職サイト・SNS・金融系など、法務判断でNGとしたドメイン
- エスカレーション — グレーゾーンは誰(法務・セキュリティ)に止まって相談するか
- インシデント — IPブロック・Cease and Desist を受けたときの停止手順
- 監査ログ — いつ・誰が・どのURLを・何件取得したか(後追い説明用)
実務でよくある判断ミス
| よくある誤解 | 実際のところ |
|---|---|
| 公開ページだから自由に使える | ToS・著作権・個人情報の制約は残る |
| robots.txt が空なら何でもOK | ToS が禁止していればスクレイピングはNG |
| 社内利用なら問題ない | 事業目的の取得は規約・不正競争の対象になりうる |
| 1秒1回なら安全 | 間隔は必要条件であって十分条件ではない |
| APIキーなしで取れるからAPI不要 | 意図的な迂回とみなされリスクが高い |
| 403ならWAF突破すればよい | ToS・不正アクセス・永久ブロックリスク。停止が先 |
| ハッシュすれば個人情報ではない | 再識別可能性の評価が必要 |
関連記事
この記事は セキュリティ テーマの一環です。あわせて読むと理解が深まる関連記事をまとめました。
| トピック | 記事 |
|---|---|
| XSS攻撃と防御の完全ガイド | XSS攻撃と防御の完全ガイド|反射型・蓄積型・DOM型の対策 |
| CSRF対策の実装ガイド | CSRF対策の実装ガイド|SameSite・Synchronizer Token・Laravel/Expressコード |
| Double Submit Cookie完全実装 | Double Submit Cookie完全実装|Synchronizer Token比較・SPA+JWT・サブドメイン攻撃 |
| Content Security Policy (CSP) 設定ガイド | Content Security Policy (CSP) 設定ガイド|XSS・クリックジャッキング対策 |
| CSP Report-Only 段階導入ガイド | CSP Report-Only 段階導入ガイド|本番を壊さずポリシーを検証する |
| セキュリティヘッダー一覧と設定ガイド | セキュリティヘッダー一覧と設定ガイド|CSP・HSTS・Referrer-Policy・Permissions-Policy |
| セキュアなCookie設定ガイド | セキュアなCookie設定ガイド|HttpOnly・Secure・SameSiteの使い分けとCSRF対策 |
| CORSエラーの対処法 | CORSエラーの対処法|「Access-Control-Allow-Origin」で解決する |
| CORSプリフライトリクエスト | CORSプリフライトリクエスト|OPTIONSが飛ぶ条件と正しい応答 |
| ローカル開発でCORSエラーが出る原因と3つの回避策 | ローカル開発でCORSエラーが出る原因と3つの回避策 |
| OAuth2 PKCE SPA実装ガイド | OAuth2 PKCE SPA実装ガイド|Authorization Code + S256 + BFFパターン |
| Passkeys・WebAuthn実装の基礎 | Passkeys・WebAuthn実装の基礎|FIDO2・Resident Key・@simplewebauthn/server |
まとめ
Webスクレイピングは強力なデータ収集手段だが、robots.txt は技術的マナー、ToS と著作権・APPI が法的・事業的な境界線になる。米国CFAAと日本の不正アクセス禁止法は「公開=自由」ではなく、技術的保護の突破・ToS・契約が争点になりうる。
実装前の優先順位:
- ToSで禁止されていないか — 禁止なら交渉か中止
- 公式APIで足りないか — 迂回スクレイピングは最後
- 個人情報を含まないか — APPI・目的・保存期限
- robots.txt をコードで尊重しているか — Disallow パスへ入らない
- 429・403・CAPTCHAで止まれるか — Anti-Bot記事 と併読
取るなら識別可能・低負荷・最小限・期限付きで設計する。どれか一つでも疑問が残ったら、コードを書く前に止まる。それが、サービスを長く運用するチームの基本だ。