UC-CRAWL-003CrawlLv3
競合調査・コンテンツ集約
競合サイトのコンテンツを集約し、テーマ・頻度・訴求を定量分析する。
Crawl API
KPI 例
- 収集記事数
- 重複除去率
- トピック網羅率
競合調査では、単発のページ保存よりも、どの URL をいつ取得したかを追えることが重要です。Crawl API を使うと、公開ページ群を定期収集し、Markdown や HTML 系出力を比較用データとして残せるため、訴求の変化や新規公開ページの増減を追いやすくなります。
誰の課題か
- 競合サイトのブログ、製品ページ、導入事例を定点観測したいマーケティング担当
- 製品訴求や情報設計の変化を、手作業ではなくデータで見たいプロダクトマネージャー
- 公開情報の範囲で継続比較を行い、社内レポートへ落とし込みたい分析チーム
推奨製品セット
| 構成要素 | 役割 | このユースケースでの使い方 |
|---|---|---|
| Crawl API | 対象ページ収集 | 競合サイトの URL 群を定期投入する |
| API Access | 認証方式 | 定期ジョブから安全に起動する |
| Scheduler / Webhook | 継続運用 | 更新監視を人手ではなくジョブに寄せる |
- Crawl API Overview では competitive research and content aggregation が主要ユースケースとして示されています。
- 比較分析の中身は自前ですが、継続収集の土台は Crawl API に寄せると再現性を持たせやすくなります。
最小実装イメージ
1. 比較したい公開ページ群を Markdown で取得する
curl -X POST "https://api.brightdata.com/datasets/v3/trigger?dataset_id=$CRAWL_DATASET_ID&include_errors=true&custom_output_fields=markdown" \
-H "Authorization: Bearer $BRIGHTDATA_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{"url":"https://competitor.example.com/blog/"},
{"url":"https://competitor.example.com/products/"},
{"url":"https://competitor.example.com/customers/"}
]'- Markdown 出力は本文比較や埋め込み生成に向いています。
- 競合分析では、まず公開トップレベルの主要導線だけに絞って始めるほうがノイズを抑えられます。
2. 取得結果を簡単な比較用テーブルに整える
import os
import time
import requests
api_key = os.environ["BRIGHTDATA_API_KEY"]
dataset_id = os.environ["CRAWL_DATASET_ID"]
headers = {"Authorization": f"Bearer {api_key}"}
trigger = requests.post(
f"https://api.brightdata.com/datasets/v3/trigger?dataset_id={dataset_id}&include_errors=true&custom_output_fields=markdown",
headers={**headers, "Content-Type": "application/json"},
json=[
{"url": "https://competitor.example.com/blog/"},
{"url": "https://competitor.example.com/products/"},
{"url": "https://competitor.example.com/customers/"},
],
timeout=60,
)
trigger.raise_for_status()
snapshot_id = trigger.json()["snapshot_id"]
while True:
progress = requests.get(
f"https://api.brightdata.com/datasets/v3/progress/{snapshot_id}",
headers=headers,
timeout=60,
)
progress.raise_for_status()
status = progress.json()["status"]
if status == "ready":
break
if status == "failed":
raise RuntimeError(f"snapshot failed: {snapshot_id}")
time.sleep(10)
rows = requests.get(
f"https://api.brightdata.com/datasets/v3/snapshot/{snapshot_id}?format=json",
headers=headers,
timeout=120,
).json()
for row in rows:
markdown = row.get("markdown", "")
print({
"url": row.get("url"),
"chars": len(markdown),
"has_pricing": "価格" in markdown or "pricing" in markdown.lower(),
"has_case_study": "導入事例" in markdown or "case study" in markdown.lower(),
})- 最初は単純なキーワード比較だけでも、更新傾向の把握には十分です。
- 取得テキストをそのまま BI や埋め込みパイプラインへ流す場合も、
snapshot_idを残しておくと監査しやすくなります。
運用ポイント
- 競合調査は公開情報の範囲で行い、取得対象、保存期間、社内共有範囲を決めてから回すべきです。
- 更新比較では、URL ごとの差分だけでなく、取得日時と
snapshot_idを持つと再確認しやすくなります。 - 競合ごとに取得対象を増やしすぎると分析軸がぶれるため、まずはブログ、製品、導入事例など固定カテゴリで揃えるのが有効です。
- 定期収集は scheduler support や webhook delivery を前提に設計し、人手の実行に依存しない形へ寄せます。