TikTok競合分析:週間コンテンツレポートを作成する
Web Data Collection Specialist
TL;DR:
- TikTok競合分析は固定アカウントセットから始まります。 投稿を収集する前に、報告書に含まれる公共ブランドアカウントを記録します。
- 比較可能なサンプルはラベルなしの合計より重要です。 各アカウントに対して同じ要求カウントと収集ウィンドウを使用し、返されたアイテム数を開示します。
- コンテンツカテゴリーにはレビュー可能なルールが必要です。 一致したフレーズとハッシュタグを各テーマラベルの傍に保存し、レビュアーが分類を修正できるようにします。
- 中央値は1つのバイラル投稿の影響を減少させます。 分布と観察されたサンプルのペースを合計とともに報告します。
- 週次報告は観察されたサンプルを説明します。 検証済みのフル期間のカバレッジがない場合、アカウントの正確な全体投稿頻度を主張することはできません。
- 無料で開始。 新しいScrapelessアカウントには無料クレジットが含まれています。Scrapelessダッシュボードでアカウントを作成してください。
Introduction: competitor reports fail at the sampling step
公共ブランドフィードは比較が簡単に不適切になります。1つのアカウントが30の観察された投稿を貢献する一方、別のアカウントは8の投稿を提供し、1つの外れ値が平均エンゲージメントを支配する可能性があります。洗練されたチャートはそのミスマッチを修正することはありません。
このワークフローは、選択された公共アカウントから週次のTikTok競合コンテンツレポートを構築します。範囲を持つ投稿サンプルを収集し、シンプルなレビュー可能なルールでコンテンツにラベルを付け、中央値と範囲でエンゲージメントを要約し、最終報告書で収集スコープを可視化します。
アカウントセットがブランド競合ではなくクリエイターで構成されている場合は、TikTokインフルエンサー分析ガイドを使用してください。
Pipeline at a Glance
実用的なTikTok競合分析パイプラインには5つのステージがあります:
- 競合者リストと報告期間を定義します。
- 各公共ユーザー名を
sec_uidに解決します。 - 各アカウントに対して同じ範囲を持つ投稿サンプルを収集します。
- 説明とハッシュタグを透明なルールで分類します。
- 観察されたサンプルを週次報告に集約します。
パイプラインは、生の応答と正規化された行を保存し、要約を計算する前にそれらを分離します。その分離により、報告の変更が別の収集ランを強制することがありません。
Prerequisites
- ScrapelessダッシュボードからのScrapelessアカウントとAPIトークン
- 標準ライブラリを含むPython 3
- 公共ブランドユーザー名のレビュー済みリスト
- 固定の要求投稿数と収集タイムスタンプ
- 人間が検査できる小さなカテゴリー辞書
- 下記のコード用に
SCRAPELESS_API_KEYとしてエクスポートされたライブトークン
組み立てられた例は、読者のAPI資格情報と選択されたアカウントが必要なため、前提条件のギャップとしてマークされています。変換ロジックは含まれていますが、記事にはプライベートな資格情報や作成されたアクターの出力は含まれていません。
Stage 1: Define a Comparable Competitor Set
競合者リストは報告仕様の一部です。すべてのアカウントに安定した内部ラベル、公共ユーザー名、含まれる理由、リストが承認された日付を与えてください。大規模な出版社や個人クリエイターを同様のサイズのブランドアカウントのセットに静かに追加することは避けてください。そのコンテンツ量は比較を歪める可能性があります。
コンパクトなロスターは次のように見える場合があります:
| account_label | username | inclusion_reason |
|---|---|---|
| ブランドA | brand_a |
直接のカテゴリー競合 |
| ブランドB | brand_b |
同じオーディエンスと価格帯 |
| ブランドC | brand_c |
隣接カテゴリーのベンチマーク |
リストはユーザー提供のままにしてください。ここで使用されているアクターは、完全な競争市場を発見したり、2つのアカウントが商業的に競争していることを証明したりするものではありません。
Stage 2: Collect the Same Bounded Post Sample
収集ステージはscraper.tiktok.user.detailを介して各ユーザー名を解決し、返されたsec_uidをscraper.tiktok.user.workに供給します。投稿リクエストはcursorとcountを受け入れます。このワークフローは、すべてのアカウントに対して同じ要求数でドキュメントされたカーソル"0"から始まります。
要求されたカウントと返されたカウントを別々に保存します。1つのアカウントが使用可能なアイテムを少なく返した場合、そのメトリクスをゼロ値の行で埋めることは避けてください。週次報告でその違いを開示します。
投稿応答には、説明、ハッシュタグ、作成時間、公共再生およびエンゲージメント数、URL、固定ステータス、言語、音楽、字幕、およびメディアフィールドが含まれることがあります。オプションの値は空の場合があります。欠落している値は、ソースの意味が別の解釈を正当化するまで欠落したままとしてください。
Scrapelessでスクレイピングを開始
Scrapelessでウェブスクレイピングと自動化のワークフローをパワーアップ!
今日はサインアップして**$5の無料クレジット**をゲット — クレジットカードは必要ありません。
今すぐScrapeless Dashboardで無料クレジットを請求しましょう。
ステージ3: レビュー可能なルールでコンテンツを分類する
コンテンツ分類は、各ラベルの背後にある証拠を保存する必要があります。週次運営報告のために、シンプルなルールテーブルがよく使われます。
| テーマ | 説明フレーズ | ハッシュタグ |
|---|---|---|
| プロダクト教育 | how to, tips, explained |
tutorial, howto |
| ローンチ | new, introducing, available now |
launch, newproduct |
| プロモーション | sale, discount, limited offer |
sale, deal |
| コミュニティ | duet, challenge, your turn |
challenge, community |
これらのラベルは編集ルールであり、提供された事実ではありません。一致した用語を保存し、ルールが合致しない場合はuncategorizedを許可します。レビュワーは、分類エラーを収集エラーから区別できます。
ルールベースのラベルはオーバーラップも明らかにします。投稿は同時に商品ローンチとプロモーションについて議論することがあります。複数のラベルを許可するか、文書化された優先順位を定義してください。辞書順に目に見えない形で決定させてはいけません。
ステージ4: エンゲージメントと観測された頻度の要約
公開エンゲージメント数は、収集時にキャプチャされた累積観測です。これらは、ブランドのパフォーマンスの完全な指標として扱うのではなく、宣言されたサンプル内で比較してください。
アカウントごとの有用なフィールドは以下の通りです:
- 戻された投稿数
- 観測サンプル内の最も早いおよび最新の作成時刻
- 再生、いいね、コメント、シェアの中央値
- スプレッドを示すための最小および最大値
- 分類されたサンプル内のテーマシェア
- サンプル内のピン留めされた投稿数
- 隣接するサンプル投稿日間の観測されたギャップ
Pythonのstatistics モジュールドキュメントは、実装に使用される中央値操作を定義しています。中央値は、観測された中間値を示し、異常に大きな投稿の影響を制限しますが、サンプリングバイアスを排除するわけではありません。
投稿の頻度については慎重な言葉選びが必要です。収集されたサンプルが報告期間の完全なカバレッジを証明しない場合、「収集サンプル内の観測された投稿」と、最も早い項目と最新の項目の間の日付範囲を報告してください。その数をアカウントの正確な週ごとの投稿頻度として提示してはいけません。
ステージ5: Pythonパイプラインを組み立てる
以下のスクリプトは、提供された各ユーザー名のために固定された初期サンプルを収集し、1つ以上のコンテンツテーマを割り当て、投稿レベルの行とアカウントレベルの要約の両方を書き込みます。PythonのCSVモジュールドキュメントはエクスポート形式をカバーしており、NISTプライバシーフレームワークはアクセス、保持、データ最小化の決定のための有用な構造を提供します。
注意: 以下のコードは、
SCRAPELESS_API_KEYにライブScrapeless APIトークンを必要とし、読者によって提供される実際の公開ユーザー名が必要です。
python
import csv
import json
import os
from datetime import datetime, timezone
from statistics import median
from urllib.request import Request, urlopen
ENDPOINT = "https://api.scrapeless.com/api/v1/scraper/request"
TOKEN = os.environ["SCRAPELESS_API_KEY"]
ACCOUNTS = [name.strip().lstrip("@") for name in os.environ[
"TIKTOK_COMPETITOR_USERNAMES"
].split(",") if name.strip()]
REQUESTED_COUNT = 20
THEMES = {
"product_education": {"how to", "tips", "explained", "tutorial", "howto"},
"launch": {"new", "introducing", "available now", "launch", "newproduct"},
"promotion": {"sale", "discount", "limited offer", "deal"},
"community": {"duet", "challenge", "your turn", "community"},
}
def run_actor(actor, actor_input):
data = json.dumps({"actor": actor, "input": actor_input}).encode()
request = Request(
ENDPOINT,
data=data,
headers={"x-api-token": TOKEN, "content-type": "application/json"},
method="POST",
)
with urlopen(request, timeout=60) as response:
return json.load(response)
def labels_for(item):
hashtag_values = []
for tag in item.get("hashtags") or []:
hashtag_values.append(
str(tag.get("name", "")) if isinstance(tag, dict) else str(tag)
)
searchable = " ".join([
str(item.get("description") or ""),
" ".join(hashtag_values),
]).lower()
labels = [
theme for theme, terms in THEMES.items()
if any(term in searchable for term in terms)
]
return labels or ["uncategorized"]
def metric(item, name):
value = item.get(name)
return value if isinstance(value, (int, float)) else None
collected_at = datetime.now(timezone.utc).isoformat()
rows = []
for username in ACCOUNTS:
profile = run_actor("scraper.tiktok.user.detail", {"unique_id": username})
response = run_actor(
"scraper.tiktok.user.work",
{"sec_uid": profile["sec_uid"], "cursor": "0", "count": REQUESTED_COUNT},
)
with open(f"{username}-posts-raw.json", "w", encoding="utf-8") as raw_file:
json.dump(response, raw_file, ensure_ascii=False, indent=2)
for item in response.get("items") or []:
rows.append({
"account": username,
"collected_at": collected_at,
"requested_count": REQUESTED_COUNT,
"post_id": str(item.get("id") or item.get("post_id") or ""),
"post_url": item.get("url") or item.get("post_url") or "",
"created_at": item.get("create_time") or item.get("date") or "",
"themes": "|".join(labels_for(item)),
"play_count": metric(item, "play_count"),
"like_count": metric(item, "like_count"),
"comment_count": metric(item, "comment_count"),
"share_count": metric(item, "share_count"),
"is_pinned": item.get("is_pinned"),
})
with open("competitor-posts.csv", "w", newline="", encoding="utf-8") as output:
writer = csv.DictWriter(output, fieldnames=rows[0].keys() if rows else ["account"])
writer.writeheader()
writer.writerows(rows)
with open("competitor-weekly-summary.csv", "w", newline="", encoding="utf-8") as output:
fields = ["account", "observed_posts", "median_plays", "median_likes"]
writer = csv.DictWriter(output, fieldnames=fields)
writer.writeheader()
for username in ACCOUNTS:
account_rows = [row for row in rows if row["account"] == username]
plays = [row["play_count"] for row in account_rows if row["play_count"] is not None]
likes = [row["like_count"] for row in account_rows if row["like_count"] is not None]
writer.writerow({
"account": username,
"observed_posts": len(account_rows),
"median_plays": median(plays) if plays else "",
"median_likes": median(likes) if likes else "",
})
要約は意図的にobserved_postsと言っています。ライブレスポンスで正確なタイムスタンプ表示を確認した後に、テーマカウント、値の範囲、サンプルデート範囲を追加します。
週次競合コンテンツ報告テンプレート
有用な報告は、付録の前に1ページに収まります:
| セクション | 含む | スコープノート |
|---|---|---|
| 収集要約 | アカウント名簿、収集時間、要求および返されたカウント | 結果が収集されたサンプルをカバーしていると記載する |
| コンテンツミックス | テーマカウントとシェア、未分類率 | 現在のルール辞書を添付する |
| エンゲージメント | メトリックおよびアカウント別の中央値と範囲 | 収集時の公開累積カウント |
| 頻度 | 観測された投稿日とギャップ | カバレッジなしのフル期間頻度を主張しない |
| 注目すべき投稿 | 投稿URL、テーマ、メトリックコンテキスト、レビュワーノート | 観察から解釈を分ける |
| アクション | 次回の報告でテストする質問 | 保護されたクリエイティブ資産をコピーしない |
投稿レベルの行は付録またはリンクされたCSVに配置してください。メインレポートは、読者がサンプルアカウント、投稿URL、収集時間、分類ルールに基づいてすべての結論を追跡できるようにする必要があります。
公共アカウントデータを責任を持って扱う
公開プロファイルには、個人データが含まれている可能性があります。報告目的に制限されたアカウントセットを制限し、生のレスポンスへのアクセスを制限し、削除スケジュールを定義し、キャプション、言語、または視覚コンテンツから敏感な特徴を推測しないようにします。
競合分析は、観察可能なコンテンツパターンを説明する必要があります。メディアを再公開したり、保護されたクリエイティブ作品を模倣したり、ブランドやクリエイターに隠された意図を割り当てたりするべきではありません。商業的な意思決定に影響を与える可能性のあるラベルに対しては、人間のレビューを保持してください。
Scrapelessは、Scraping APIを通じてコレクションアクターを提供します。リクエストされたアカウントとサンプル数をプロダクションプランに変換する際は、現在の価格ページを確認してください。
結論:比較を監査可能にする
TikTokの競合分析は、すべての数字がその範囲を持つときに有用になります。アカウント名簿を修正し、比較可能なサンプルをリクエストし、生のレスポンスを保持し、分類ルールを公開し、返されたカウントの中央値を報告してください。その結果は、サンプルがすべてのアカウントの完全なビューであるかのように装うことなくレビューをサポートする毎週のコンテンツレポートになります。
毎週の競合レポートを作成する準備はできましたか?
コレクションと報告のパターンについて話し合うために、Scrapeless DiscordまたはTelegramコミュニティに参加してください。名簿とサンプル方針が整ったら、Scrapelessダッシュボードでアカウントを作成してください。
FAQ
Q: TikTok競合分析とは何ですか?
TikTok競合分析は、ユーザー定義のアカウントセット全体で観察可能な公開コンテンツとエンゲージメントパターンを比較します。防御可能なレポートは、コレクションの時間、サンプルサイズ、および分類ルールも明示します。
Q: 毎週の競合レポートにはどのメトリックが含まれるべきですか?
毎週の競合レポートには、観察された投稿数、サンプリングされた日付範囲、コンテンツテーマのミックス、中央値の公開エンゲージメントカウント、範囲、および注目すべき投稿へのリンクが含まれる可能性があります。各メトリックはサンプル観察としてラベル付けされるべきです。
Q: サンプルは正確な投稿頻度を示すことができますか?
サンプルは、コレクションが指定された期間の完全なカバレッジを確認している場合のみ、正確な投稿頻度を示します。そうでない場合は、観察された日付と収集されたサンプル内のギャップを報告してください。
Q: なぜ平均エンゲージメントの代わりに中央値エンゲージメントを使用するのですか?
中央値エンゲージメントは、異常に大きな観察値の影響を軽減します。それは依然としてサンプルの質に依存するため、サンプルカウントと範囲をその隣に公開してください。
Q: ワークフローにはブラウザパーサーやプロキシの設定が必要ですか?
APIは、提供された識別子のサポートされている公開アカウントおよび投稿フィールドを返します。報告パイプラインは、アカウント、サンプル制限、ストレージ、分類、およびレビューを定義します。
Q: 公開競合コンテンツを収集することは合法ですか?
合法性は、管轄、目的、データ、アクセス方法、および適用される条件に依存します。必要な公開フィールドのみを収集し、知的財産を尊重し、保持を制限し、特定の使用について法的アドバイスを取得してください。
Scrapelessでは、適用される法律、規制、およびWebサイトのプライバシーポリシーを厳密に遵守しながら、公開されているデータのみにアクセスします。 このブログのコンテンツは、デモンストレーションのみを目的としており、違法または侵害の活動は含まれません。 このブログまたはサードパーティのリンクからの情報の使用に対するすべての責任を保証せず、放棄します。 スクレイピング活動に従事する前に、法律顧問に相談し、ターゲットウェブサイトの利用規約を確認するか、必要な許可を取得してください。



