安全確認つき Webデータ取得ツール
ScraperKit 動作デモ

指定サイトから商品名・価格などを自動で取り出し、CSVに保存するツールです。取得の前に「取得禁止サイトに当たらないか」「robots.txtは許可しているか」を自動で確認し、該当すれば止まって理由をお知らせします。
下の記録は、この仕組みを実際に動かした結果です(取得対象は動作確認用に作った架空サイトです)。

24件を取得→CSV
23/23自動テスト合格
13サイトを規範ライブラリに登録
1.5秒間隔で取得(下限1秒)

動作の流れ

  1. 設定ファイル取得先URL・取り出す項目(CSSセレクタ)・件数上限をYAML 1枚に記入。サイトが変わっても、書き換えるのはここだけ。
  2. 安全確認規範ライブラリ(取得禁止サイト一覧)と照合。該当すれば通信前に停止。続いて robots.txt を確認。
  3. 取得・抽出一覧→「次へ」→詳細ページを辿って項目を抽出。JavaScriptで描画されるページはブラウザ方式で対応。
  4. CSV保存Excelで文字化けしないUTF-8(BOM付き)。金額は数値に変換、重複は除外、実行ログも保存。

実行記録(実際のログ)

① 通常取得(一覧3ページ+詳細24ページ)完了

$ python -m scraper_kit run config.demo.yaml
16:10:02 == 開始:ミナトマーケット 商品一覧(デモ) / ScraperKit 1.0
16:10:02 [設定] 取得先=https://scraper-guard-demo.pages.dev/portal/items/ 方式=http 間隔=1.5秒 最大5ページ/100件
16:10:02 [規範] 規範ライブラリ 13 件と照合:該当なし
16:10:03 [robots] https://scraper-guard-demo.pages.dev/robots.txt を読み込み(Crawl-delay=1)
16:10:04 [取得] 1ページ目 https://scraper-guard-demo.pages.dev/portal/items/ → 8件
16:10:17 [取得] 2ページ目 https://scraper-guard-demo.pages.dev/portal/items/page2.html → 8件
16:10:30 [取得] 3ページ目 https://scraper-guard-demo.pages.dev/portal/items/page3.html → 8件
16:10:42 [完了] 24件 / 27リクエスト / スキップ0件 / 個人情報らしき値の非表示化24件
16:10:42 [出力] output\minato_items.csv
exit=0

② JavaScriptで描画されるページ完了

$ python -m scraper_kit run config.demo-js.yaml
16:10:43 == 開始:ミナトマーケット 新着(JavaScript描画ページ) / ScraperKit 1.0
16:10:43 [設定] 取得先=https://scraper-guard-demo.pages.dev/portal/js/ 方式=browser 間隔=1.5秒 最大1ページ/50件
16:10:43 [規範] 規範ライブラリ 13 件と照合:該当なし
16:10:44 [robots] https://scraper-guard-demo.pages.dev/robots.txt を読み込み(Crawl-delay=1)
16:10:48 [取得] 1ページ目 https://scraper-guard-demo.pages.dev/portal/js/ → 6件
16:10:48 [完了] 6件 / 1リクエスト / スキップ0件 / 個人情報らしき値の非表示化0件
16:10:48 [出力] output\minato_js_items.csv
exit=0

③ 取得禁止サイトを指定した場合(通信せずに停止)停止

$ python -m scraper_kit check https://www.instagram.com/explore/
16:10:48 [停止] 取得を中止しました:www.instagram.com は規範ライブラリで「禁止」に該当します。
  理由:書面許可のない自動化手段によるデータ収集を禁止する旨の公式表示
  根拠:https://www.instagram.com/robots.txt 冒頭の Notice(原文確認)
  → このサイトからの自動収集は実行できません(設定による解除不可)。公式 API・データ提供の有無をご確認ください。
exit=3

④ 「要確認」サイトを指定した場合(確認記録がなければ停止)停止

$ python -m scraper_kit check https://www.amazon.co.jp/dp/B000000000
16:10:49 [停止] 取得を中止しました:www.amazon.co.jp は規範ライブラリで「要確認」に該当します。
  理由:公式の商品情報 API(Product Advertising API 等)の利用が前提。ご利用条件の該当条文は取得できず未確認
  根拠:https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=GLSBYFE9MGKKQXXM (確認時 503 で閲覧不可)
  → 規約を確認のうえ実行する場合は、設定ファイルの review_confirmations に domain / by(確認者)/ date / note を記録してください。
exit=3

⑤ robots.txt が不許可のページ(会員エリア)取得不可

$ python -m scraper_kit check https://scraper-guard-demo.pages.dev/portal/members/
16:11:11 [robots] https://scraper-guard-demo.pages.dev/robots.txt を読み込み(Crawl-delay=1)
16:11:11 [判定] https://scraper-guard-demo.pages.dev/portal/members/ → robots.txt上は取得不可
exit=5

取得結果(CSVの先頭8行)

商品名カテゴリ価格(円)出品者型番在庫出荷目安連絡先
木製ペン立て ウォールナット文具2480出品:港雑貨店MM-101-001在庫あり2〜4営業日メール:[メール 非表示] / 電話:[電話番号 非表示]
リングノート A5 方眼文具680出品:ミナト文具舗MM-102-002在庫あり3〜5営業日メール:[メール 非表示] / 電話:[電話番号 非表示]
真鍮ブックマーク 3本組文具1280出品:ミナト文具舗MM-103-003在庫あり1〜3営業日メール:[メール 非表示] / 電話:[電話番号 非表示]
万年筆インク 深緑 30ml文具1650出品:ミナト文具舗MM-104-004在庫あり2〜4営業日メール:[メール 非表示] / 電話:[電話番号 非表示]
ステンレス製 計量スプーンキッチン1180出品:海風キッチンMM-105-005残りわずか3〜5営業日メール:[メール 非表示] / 電話:[電話番号 非表示]
鋳鉄の小さなフライパン 16cmキッチン3980出品:海風キッチンMM-106-006在庫あり1〜3営業日メール:[メール 非表示] / 電話:[電話番号 非表示]
麻のキッチンクロス 2枚組キッチン1480出品:海風キッチンMM-107-007在庫あり2〜4営業日メール:[メール 非表示] / 電話:[電話番号 非表示]
琺瑯ポット 1.2Lキッチン4380出品:海風キッチンMM-108-008在庫あり3〜5営業日メール:[メール 非表示] / 電話:[電話番号 非表示]

詳細ページにあった「メール・電話番号」は、既定で [非表示] に置き換えて保存します(個人情報の意図しない持ち出しを防ぐため)。必要な場合は、取得の根拠を設定に記録したうえで解除できます。

規範ライブラリ(取得禁止サイトの一覧)

実行のたびに最初に読み込む blocked_sites.md です。表に行を足すだけで反映されます(プログラム修正は不要)。

ドメイン区分理由根拠(確認範囲)確認日
instagram.com禁止書面許可のない自動化手段によるデータ収集を禁止する旨の公式表示https://www.instagram.com/robots.txt 冒頭の Notice(原文確認)2026-11-03
facebook.com禁止同上(Meta Automated Data Collection Terms)https://www.facebook.com/robots.txt 冒頭の Notice(原文確認)2026-11-03
linkedin.com禁止事前の明示的許可のないロボット等によるアクセスを禁止する旨の公式表示https://www.linkedin.com/robots.txt 冒頭の Notice(原文確認)2026-11-03
x.com禁止事前の書面同意のないクロール・スクレイピングを利用規約で禁止(2023-09 改定)利用規約 https://x.com/tos / 報道 https://techcrunch.com/2023/09/08/x-updates-its-terms-to-ban-crawling-and-scraping (報道で確認。規約原文は未確認)2026-11-03
twitter.com禁止x.com と同一サービス上記 x.com に同じ2026-11-03
amazon.co.jp要確認公式の商品情報 API(Product Advertising API 等)の利用が前提。ご利用条件の該当条文は取得できず未確認https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=GLSBYFE9MGKKQXXM (確認時 503 で閲覧不可)2026-11-03
rakuten.co.jp要確認公式 API(楽天ウェブサービス)が提供されている。規約上の自動収集の扱いは未確認https://webservice.rakuten.co.jp/2026-11-03
mercari.com要確認規約・ガイドに自動収集の明文は確認できず(未確認)。私的利用を超える取得は要確認https://jp.mercari.com/terms (確認時 404)2026-11-03
tabelog.com要確認利用規約に「複写・複製」「運営の妨げ」「営利目的の利用」等の禁止があり、自動取得が該当し得る(クローラーの明文なし)https://tabelog.com/help/rules/ 第6条・第9条2026-11-03
shopping.yahoo.co.jp要確認公式の商品検索 API(Yahoo!ショッピング Web API)が提供されている。規約上の扱いは未確認https://developer.yahoo.co.jp/2026-11-03
google.com要確認検索結果ページ(/search)は robots.txt で取得不可。Google の規約は自動化クエリを制限https://www.google.com/robots.txt2026-11-03
lancers.jp要確認他社プラットフォーム。サイト内の情報は利用規約・ガイドライン上の取り扱いを確認してからhttps://www.lancers.jp/robots.txt2026-11-03
crowdworks.jp要確認同上https://crowdworks.jp/robots.txt2026-11-03

根拠欄には「原文確認/報道のみ/未確認」まで正直に書いています。確認できなかったサイトを「禁止」とは書かず「要確認」にしています。

安全のために組み込んでいること

することを制限する

  • 取得禁止サイトは通信前に停止
  • robots.txt を毎回確認(Crawl-delay も尊重)
  • アクセス間隔は最低1秒(設定で下げられません)
  • 最大ページ数・最大件数の上限
  • 連絡先入りのUser-Agentで名乗って取得
  • メール・電話番号らしき値は既定で非表示化
  • 他ドメインへのリンクは辿らない

しないことを決めている

  • 403/429が続いたら、回避せず停止(プロキシ切替・UA偽装なし)
  • ログインが必要なページは対象外(ログイン画面に遷移したら停止)
  • CAPTCHAの突破は行わない
  • robots.txt を無視する設定は、運営者本人の許可の記録がないと動かない
  • 実行ごとに、何を・どの条件で取得したかのログを保存

設定ファイルの例

取得先が変わっても、この1枚を書き換えるだけです。

# ScraperKit 設定ファイル(デモ用:架空ポータル「ミナトマーケット」の商品一覧)
# 取得先が変わっても、このファイルの「start_url」と「セレクタ」を書き換えるだけで使えます。

name: ミナトマーケット 商品一覧(デモ)
contact: "ops@example.com"        # 取得先から連絡できる窓口。User-Agentに入ります(必須)
start_url: https://scraper-guard-demo.pages.dev/portal/items/
render: http                      # http … 通常取得 / browser … JavaScriptで描画されるページ
delay_sec: 1.5                    # アクセス間隔(秒)。1秒未満は自動で1秒に引き上げ
max_pages: 5                      # 一覧ページの最大数
max_items: 100                    # 取得する最大件数

list:
  item: "article.item"            # 1商品ぶんのかたまり
  next: "a[rel=next]"             # 「次へ」リンク

fields:                           # 一覧ページから取る項目(CSVの列になります)
  name:     { selector: "h2.name" }
  category: { selector: ".category" }
  price:    { selector: ".price", type: price }     # 「¥2,480(税込)」→ 2480
  shop:     { selector: ".shop" }
  url:      { selector: "a.detail", attr: href, type: url }

detail:                           # 詳細ページも取る場合(不要なら、この4行を削除)
  from_field: url
  fields:
    model: { selector: "dd.model" }
    stock: { selector: "dd.stock" }
    ship:  { selector: "dd.ship" }
    contact: { selector: "dd.contact" }   # 連絡先らしき値は既定で非表示化されます

pii:
  mode: mask                      # mask … 非表示化(既定)/ drop … 空欄 / keep … そのまま(pii.basisに根拠の記録が必要)

output:
  csv: output/minato_items.csv
  encoding: utf-8-sig             # Excelで開いても文字化けしない(cp932も指定可)
  dedupe_key: url                 # 同じURLの重複を除外

# 規範ライブラリで「要確認」と出たサイトを、規約確認のうえ実行する場合だけ記入します:
# review_confirmations:
#   - { domain: example.co.jp, by: 担当者名, date: 2026-11-10, note: "規約第○条を確認。公式の許可あり" }

自動テスト(23件すべて合格)

  • ✔ 規範ライブラリのファイル形式(全行に理由・根拠・確認日がある)
  • ✔ 「禁止」サイト(Instagram/Facebook(サブドメイン含む)/LinkedIn/X/Twitter)が通信前に停止(5件)
  • ✔ 「禁止」は設定ファイルでも解除できない
  • ✔ 「要確認」サイトは停止し、確認者・日付の記録がある場合のみ記録付きで実行
  • ✔ 確認記録が不完全なら解除されない
  • ✔ 規範ライブラリ外のサイトは通過する
  • ✔ アクセス間隔の下限(1秒)を強制
  • ✔ 個人情報らしき値の非表示化/空欄化、解除には根拠の記録が必須
  • ✔ 金額の数値化(「¥12,800(税込)」→ 12800)
  • ✔ ページ送り・重複除外・CSV出力(BOM付きUTF-8)
  • ✔ 最大件数・最大ページ数の上限
  • ✔ robots.txt で不許可のURLには一切アクセスしない
  • ✔ robots.txt の取得エラー(5xx)では安全側に停止
  • ✔ robots.txt を無視する設定は運営者本人の許可の記録が必須
  • ✔ 403 では再試行も回避もせず停止
  • ✔ 429 では待機→再試行→それでもだめなら停止
  • ✔ ログイン画面へ遷移したら停止
  • ✔ 他ドメインへのリンクは辿らない
  • ✔ 禁止サイトを開始URLにすると、通信も出力ファイルも作らない

pytest で実行した結果です。テストは納品物に含まれ、納品後もお手元で再実行できます。

制限事項(正直に)