TikTokキャンペーン報告と公開投稿メトリクス
Lead Scraping Automation Engineer
TL;DR:
- TikTokキャンペーンの報告は、ユーザー定義の roster から始まります。 収集されたレコードと一致する前に、キャンペーンアカウントと投稿IDをリストしてください。
- キャンペーン投稿は収集されたサンプルに存在しなければなりません。 存在しない投稿をゼロパフォーマンスに変換するのではなく、一致しないロスターエントリを表示し続けてください。
- タイムスタンプ付きスナップショットは累積カウンターをデルタに変えます。 同じ投稿IDとメトリックを共有している場合にのみ、以前に観察された値から後に観察された値を引いてください。
- 公共のエンゲージメントは帰属ではありません。 再生、いいね、コメント、共有、収集、再投稿のカウントは、一意のリーチ、売上、またはROIを証明するものではありません。
- 配布はキャンペーンの形を示します。 合計と共に中央値、範囲、トップ投稿シェアを報告してください。
- 開始は無料です。 新しいScrapelessアカウントには無料クレジットが含まれています; Scrapeless Dashboardでアカウントを作成してください。
Introduction: campaign membership must be explicit
公共の投稿メトリックは、狭い質問に答えます:記録された時間に既知の投稿に対してどのカウンターが表示されたか? 彼らは誰が投稿を見たか、誰が製品を購入したか、またはどのインタラクションがコンバージョンを引き起こしたかを特定しません。
このガイドは、その境界に基づいてTikTokキャンペーン報告を構築します。ユーザーは参加するアカウントと投稿IDを提供し、パイプラインは収集された公共投稿のサンプルに対してそれらのIDを一致させ、繰り返しスナップショットを生成してメトリックのデルタを作成します。最終報告は、一致した投稿、一致しないロスターエントリ、累積値、および間隔の変化を分けます。
投稿収集に先立つアカウント解決ステップについては、TikTokプロファイルスクレーパーガイドを参照してください。
Pipeline at a Glance
公共投稿キャンペーンレポートは、6つのステージがあります:
- キャンペーンロスターと報告の境界を定義します。
- リストされた各公共アカウントを
sec_uidに解決します。 - 各アカウントのために限定された投稿サンプルを収集します。
- 収集した項目を提供されたキャンペーン投稿IDと一致させます。
- タイムスタンプ付きメトリックスナップショットを保存し、比較可能なデルタを計算します。
- 一致したカバレッジ、分布、および注目すべき投稿を要約します。
ロスターはこのレポートの帰属メンバーシップを定義します。スクレイパーは、どの投稿がキャンペーンに属するかを発見せず、言及またはハッシュタグだけでは、報告規則がそう指示しない限り、投稿を追加すべきではありません。
Prerequisites
- Scrapeless DashboardからのScrapelessアカウントとAPIトークン
- アカウントのユーザー名と正確な投稿IDを含むキャンペーンロスター
- 固定収集ポリシーとデルタのための少なくとも2つのタイムスタンプ付き観測
- 以下のコードのために
SCRAPELESS_API_KEYとしてエクスポートされたライブトークン
この例には、読者のAPI認証情報、キャンペーンロスター、ライブ公共投稿に依存しているため、前提条件のギャップがあります。実際のキャンペーン結果としてサンプル出力は表示されません。
Stage 1: Build the Campaign Roster
ロスターはレポートのコントロールテーブルです。各行には、キャンペーンID、公共ユーザー名、投稿ID、既知であれば期待される投稿URL、キャンペーンチームから提供された場合の計画された公開日、および人間が読めるラベルが含まれている必要があります。
| campaign_id | username | post_id | asset_label |
|---|---|---|---|
| autumn_launch | creator_a |
1234567890123456789 |
商品デモ |
| autumn_launch | creator_b |
2345678901234567890 |
チュートリアル |
投稿IDは文字列として保持してください。大きな識別子は、スプレッドシートや分析ツールが数値に強制する際に精度を失う可能性があります。
ロスターは、必要な投稿とオプションの投稿を区別する必要があります。収集されたサンプルに表示されない必要な投稿には、unmatchedのステータスとレビューノートが必要です。そのメトリックは未知であり、ゼロではありません。
Stage 2: Collect Public Posts for Listed Accounts
収集パスはscraper.tiktok.user.detailを使用してunique_idをsec_uidに解決し、その後scraper.tiktok.user.workを使用して公共投稿を要求します。投稿リクエストはcursorとcountをサポートし、その応答にはitems配列が含まれています。
比較可能なアカウントには同じリクエスト数を使用しますが、各アカウントの返された数を報告してください。利用可能なドキュメントは、普遍的な完全履歴ループを確立せずにカーソル入力を確認します。収集されたサンプルの外にキャンペーン投稿がある場合は、一致しないとマークし、現在の応答とドキュメントで確認された継続ルールを通じてのみ収集を拡張してください。
各収集ランには独自のUTCタイムスタンプが必要です。投稿レベルのメトリックが報告ロジックの変更によって再構築できるように、そのランの下に生のアクター応答を保存してください。
Scrapelessでのスクレイピング開始
Scrapelessであなたのウェブスクレイピングと自動化ワークフローにパワーアップ!
今日サインアップして**$5の無料クレジット**をゲット — クレジットカードは不要です。
今すぐScrapeless Dashboardで無料クレジットを取得してください。
ステージ 3: ギャップを隠さずに投稿を一致させる
可能な限り、正確な文字列の投稿IDで一致させます。URLはレビュー担当者に役立ちますが、URL解析は両方が利用可能な場合に安定した識別子の代わりにはなりません。
一致テーブルはすべてのロースター行を保持する必要があります:
| ステータス | 意味 | レポート処理 |
|---|---|---|
matched |
収集されたアイテムに正確な投稿IDが表示されます | タイムスタンプ付きスナップショットを保存 |
unmatched |
投稿IDはロースターにありますがサンプルにはありません | カバレッジが欠けていることを示し、ゼロではない |
unexpected |
収集された投稿はキャンペーンロースターにありません | キャンペーン合計の外に保持 |
duplicate |
同じ投稿IDが入力またはストレージに複数回表示されます | 集計前に解決 |
この調整ステップは、キャンペーン操作と公開データ収集の間の監査履歴です。これにより、ダッシュボードが必要な投稿を静かに削除したり、似たようなハッシュタグを使用して無関係な投稿を追加したりすることを防ぎます。
ステージ 4: タイムスタンプ付きのメトリックスナップショットを保存
スナップショット行にはキャンペーンID、投稿ID、アカウント、投稿URL、収集時間、作成時間、および応答に存在する各公開カウンターを含める必要があります。欠けているフィールドはゼロではなくnullとして保存してください。
SQLiteは、複合キーが重複観察を防ぐことができるため、コンパクトなローカル履歴に適しています。SQLite CREATE TABLEドキュメントでは、各投稿と収集時間ごとに1行を強制できる主キーおよびテーブル制約について説明しています。
sql
CREATE TABLE IF NOT EXISTS campaign_post_snapshots (
campaign_id TEXT NOT NULL,
post_id TEXT NOT NULL,
collected_at TEXT NOT NULL,
account TEXT NOT NULL,
post_url TEXT,
play_count INTEGER,
like_count INTEGER,
comment_count INTEGER,
share_count INTEGER,
collect_count INTEGER,
repost_count INTEGER,
PRIMARY KEY (campaign_id, post_id, collected_at)
);
このローカルスキーマには外部前提条件がなく、API資格情報が利用可能になる前にテストできます。以下の収集コードは、同じテーブルを作成し、一致したレコードを挿入します。
ステージ 5: 差分とパフォーマンス分布を計算
メトリックの差分は、同じ投稿とフィールドのための後に観察された値から前に観察された値を引いたものです。両方の値が存在する場合にのみ計算します。プラットフォームの修正またはフィールドリセットによって負の結果が生じた場合、ゼロに書き換えるのではなく、レビューのために保持します。
投稿を比較する際には、共通のスナップショットタイムのペアを使用します。72時間観察された投稿は、明示的な年齢や間隔ラベルなしに6時間観察されたものと直接比較してはいけません。
キャンペーンの概要は、いくつかのビューから恩恵を受けます:
- ロースター投稿で分割された一致した投稿
- 最新の累積メトリック合計
- 共通のスナップショット間隔における各投稿の差分
- 各メトリックの中央値と範囲
- 合計観察回数またはインタラクションに対するトップ投稿のシェア
- nullメトリックのカウントと一致しないロースターエントリ
Pythonのstatisticsモジュールのドキュメントは中央値計算を定義しています。分布ビューは、パフォーマンスが広いか集中しているかを示すのに役立ちますが、公開カウンターの説明に留まります。
TikTok Ads Managerは、有料キャンペーンレポーティングのための別のファーストパーティ環境を提供します。そのキャンペーンパフォーマンスガイダンスは、この公開投稿ワークフローと混同すべきではありません:データソース、アクセス、使用可能なメトリックが異なります。
ステージ 6: Pythonでレポートパイプラインを構築する
以下のスクリプトはロースターCSVを読み込み、リストされた各アカウントのために制限された初期サンプルを収集し、正確な投稿IDを調整し、一致したスナップショットをSQLiteに挿入し、レビュー用のカバレッジファイルを書き込みます。
注:以下のコードは、
SCRAPELESS_API_KEYのライブScrapeless APIトークン、リーダーが提供したcampaign-roster.csv、および収集されたサンプルに表示される公開キャンペーン投稿を必要とします。
python
import csv
import json
import os
import sqlite3
from datetime import datetime, timezone
from urllib.request import Request, urlopen
ENDPOINT = "https://api.scrapeless.com/api/v1/scraper/request"
TOKEN = os.environ["SCRAPELESS_API_KEY"]
REQUESTED_COUNT = 35
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)
with open("campaign-roster.csv", newline="", encoding="utf-8") as roster_file:
roster = list(csv.DictReader(roster_file))
for row in roster:
row["username"] = row["username"].lstrip("@")
row["post_id"] = str(row["post_id"])
collected_at = datetime.now(timezone.utc).isoformat()
items_by_account = {}
for username in sorted({row["username"] for row in roster}):
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}-{collected_at[:10]}-raw.json", "w", encoding="utf-8") as raw_file:
json.dump(response, raw_file, ensure_ascii=False, indent=2)
items_by_account[username] = {
str(item.get("id") or item.get("post_id") or ""): item
for item in response.get("items") or []
}
connection = sqlite3.connect("campaign-reporting.db")
connection.execute("""
CREATE TABLE IF NOT EXISTS campaign_post_snapshots (
campaign_id TEXT NOT NULL,
post_id TEXT NOT NULL,
collected_at TEXT NOT NULL,
account TEXT NOT NULL,
post_url TEXT,
play_count INTEGER,
like_count INTEGER,
comment_count INTEGER,
share_count INTEGER,
collect_count INTEGER,
repost_count INTEGER,
PRIMARY KEY (campaign_id, post_id, collected_at)
)
""")
coverage = []
for row in roster:
item = items_by_account.get(row["username"], {}).get(row["post_id"])
status = "matched" if item else "unmatched"
coverage.append({**row, "status": status, "collected_at": collected_at})
if not item:
continue
connection.execute(
"""INSERT OR REPLACE INTO campaign_post_snapshots VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(
row["campaign_id"], row["post_id"], collected_at, row["username"],
item.get("url") or item.get("post_url"), item.get("play_count"),
item.get("like_count"), item.get("comment_count"), item.get("share_count"),
item.get("collect_count"), item.get("repost_count"),
),
)
connection.commit()
connection.close()
with open("campaign-coverage.csv", "w", newline="", encoding="utf-8") as output:
writer = csv.DictWriter(output, fieldnames=coverage[0].keys())
writer.writeheader()
writer.writerows(coverage)
次の予定の観察時間に同じ収集を実行し、キャンペーンIDと投稿IDで連続するスナップショット行を結合します。両方のメトリック値がnullでない場合にのみ各差分を計算し、結果に2つの収集タイムスタンプを保持します。
キャンペーンレポートテンプレート
レポートはパフォーマンスからカバレッジを分離する必要があります:
| セクション | 必要なフィールド | 解釈の境界 |
|---|---|---|
| ロースターカバレッジ | 必要な投稿、一致した投稿、一致しない投稿 | 収集のカバレッジを測定し、キャンペーンの成功ではない |
| スナップショットタイミング | 最初と最新の収集時間、間隔 | 差分ウィンドウを比較可能にします |
| 最新メトリック | 投稿ごとの公開カウンター | 累積観察、ユニークな人ではない |
| メトリックの変更 | 共通の間隔の各投稿の差分 | 2つのスナップショット間の変化 |
| 分布 | 中央値、範囲、トップ投稿シェア | 一致した投稿での集中を示します |
| レビューキュー | 欠けているフィールド、負の差分、一致しないID | 人間による調査が必要です |
| キャンペーンに有料メディア、アフィリエイト販売、トラッキングリンク、またはコンバージョンイベントが含まれる場合は、明確にラベル付けされたレイヤーでそれらのファーストパーティデータセットを結合します。公的なエンゲージメントカウントをその測定値の代わりに使用しないでください。 |
キャンペーンデータを責任を持って扱う
キャンペーン報告は、パブリッククリエイターコンテンツを契約、内部ラベル、または商業的決定と結びつける可能性があります。名簿と内部注釈へのアクセスを制限し、保持する個人データを最小限に抑え、帰属エラーを修正できる人を定義します。
インフルエンサー プログラムの場合、FTCの開示ガイダンスは、アメリカ合衆国における開示責任の主要な参考文献です。これは、他の法域に適用される法的助言やルールを置き換えるものではありません。
Scrapeless は、Scraping API を通じてプロファイルと投稿アクターを提供します。アカウント数とスナップショットの頻度を選択する前に、現在の料金ページ を確認してください。
結論:スナップショットが証明することを報告する
TikTok キャンペーン報告には、明示的な名簿、正確な投稿 ID マッチング、タイムスタンプ付きの観察、視認可能なカバレッジギャップが必要です。これらの制御により、公的なカウンターが一致した投稿とメトリクスの変更の監査可能な記録に変わり、リーチ、売上、帰属の主張を適切なデータソースのまま保持します。
キャンペーンメトリクス報告を作成する準備はできましたか?
データモデリングパターンを比較するために、Scrapeless Discord または Telegram コミュニティ に参加してください。キャンペーン名簿が準備できたら、Scrapeless Dashboard でアカウントを作成してください。
FAQ
Q: 公開投稿メトリクスを使用した TikTok キャンペーン報告とは何ですか?
公開投稿メトリクスを使用した TikTok キャンペーン報告は、記録された時間でユーザー定義のキャンペーン投稿セットの目に見えるカウンターを追跡します。それは、それらの観察とその変化を測定し、ユニークなリーチ、売上、因果関係の帰属ではありません。
Q: ワークフローはどの投稿がキャンペーンに属するかをどのように決定しますか?
ユーザーが提供する名簿がキャンペーンのメンバーシップを決定します。パイプラインは正確な投稿 ID を一致させ、レビューされるまでパフォーマンスタイトルから欠落または予期しない投稿を外に保ちます。
Q: メトリクスのスナップショットとデルタの違いは何ですか?
スナップショットは、一度に観察された累積公的カウンターです。デルタは、同じ投稿、メトリクス、定義された間隔の2つの有効なスナップショット間の違いです。
Q: 再生回数をキャンペーンのリーチとして報告できますか?
再生回数はユニークなキャンペーンリーチとして報告すべきではありません。これは公的な投稿カウンターであり、どれだけの異なる人々がそのコンテンツを見たかを示すものではありません。
Q: 一致しないキャンペーン投稿はゼロメトリクスを受け取るべきですか?
一致しないキャンペーン投稿は、unmatched ステータスと null メトリクスを受け取るべきです。ゼロは、収集が生成しなかった観察値を主張します。
Q: ワークフローは TikTok Ads Manager を置き換えますか?
公開投稿ワークフローは、TikTok Ads Manager や他のファーストパーティキャンペーンシステムを置き換えません。それは、サポートされている公開投稿フィールドから別のデータセットを生成します。
Q: 公開キャンペーンデータの収集は合法ですか?
合法性は、管轄、目的、データ、アクセス方法、契約、および適用される条件に依存します。必要な公的フィールドの収集に制限し、内部名簿データを保護し、特定のプログラムに対して法的助言を得ることが重要です。
Scrapelessでは、適用される法律、規制、およびWebサイトのプライバシーポリシーを厳密に遵守しながら、公開されているデータのみにアクセスします。 このブログのコンテンツは、デモンストレーションのみを目的としており、違法または侵害の活動は含まれません。 このブログまたはサードパーティのリンクからの情報の使用に対するすべての責任を保証せず、放棄します。 スクレイピング活動に従事する前に、法律顧問に相談し、ターゲットウェブサイトの利用規約を確認するか、必要な許可を取得してください。



