jsonscraper
市場
ジャーナルに戻る

生の再生数を比べずに、エンゲージメントが伸びているTikTok動画を見つける方法

検索で見つけた同じ動画の指標を一定間隔で記録し、累計人気とは分けて増加分を計算する

編集方針 誤りを報告する

特定のTikTok動画への反応が増えているかを知るには、その動画の公開指標を、以前に記録した値と比較します。1回の検索でわかるのは、それまでに蓄積された再生数や反応の数です。同じ検索で見つかった動画を繰り返し取得すれば、実行間の変化を確認できます。以下では、Pythonで検索し、指標をCSVに保存して差分を計算する、最小限の実用的な手順を紹介します。

このモニタリングで測定できること

このスクリプトは、あるテーマについて検索で見つかった動画の一覧と、検証可能な観測履歴が必要なマーケター、アナリスト、開発者に適しています。たとえば、チームが製品の発売や特定の視聴者層に関する動画を定期的に追跡し、前回の確認後に再生数、いいね、コメント、シェアが増えた動画を把握したい場合に使えます。

記事:生の再生数を比べずに、エンゲージメントが伸びているTikTok動画を見つける方法
概要:検索で見つけたTikTok動画の指標をCSVに保存し、次回の実行時に同じ動画の変化を計算するPythonの手順。
画像の役割:カバー — 中心となるアイデア
セクション:このモニタリングで測定できること
ビジュアルの内容:短尺動画の匿名化されたIDと、2つのタイムスタンプ付き指標を印刷したシートを写した編集用写真
IDを使って、同じ動画の2つの指標スナップショットを照合します。© jsonscraper · AI生成

比較の基準となる単位は、aweme_idで識別される動画です。各レコードには取得時刻、ID、説明文、URL、投稿者名、および取得可能な各種カウンターを保存します。その後、2つのスナップショットをIDで照合します。これにより、ある動画の再生数の増加を、別の動画の累計再生数と混同せずに済みます。

結果が示すのは、特定の検索クエリを特定の実行時に送って返された動画だけです。検索結果は変動する可能性があり、統計情報の一部が欠けていることもあります。そのため、スナップショットと取得時刻を保存し、レポートはテーマに該当する投稿の完全なカタログではなく、すでに見つかった動画の観測結果として扱うとよいでしょう。

APIを使った取得の仕組み

TikTok Scraper APIのドキュメントには、GETルート/searchVideoが記載されています。検索にはkeyword文字列が必須です。追加パラメーターにはcount、region、sort_by、date_postedがあります。APIキーはlicense_keyとして渡します。リファレンスに記載されたベースURLはhttps://tiktok.evelode.comです。

レスポンスには外側のステータスと、tiktokオブジェクトが含まれます。検索結果の動画は、tiktok.aweme_list、またはtiktok.search_item_list[].aweme_info内に格納される場合があります。以下の処理コードは、どちらの形式にも対応しています。指標はstatisticsから取得し、play_count、digg_count、comment_count、share_countを読み取ります。値がない場合はゼロに置き換えず、空欄として保存します。

ルートのリファレンスには、検索結果をページ送りするためのcursorと、選択可能な値とともにdate_postedおよびsort_byが記載されています。シンプルで再現可能なモニタリングであれば、まず結果の1ページを取得してレスポンスを記録し、必要に応じてページネーションを追加すれば十分です。ページネーションが必要な場合は、取得したカーソルを変換せずに渡してください。

Pythonでの実用例

python -m pip install requestsを実行してrequestsライブラリをインストールし、環境変数JSONSCRAPER_TIKTOK_LICENSE_KEYにキーを設定します。このスクリプトは検索語句を引数に取り、見つかったスナップショットを1つのCSVファイルに追記します。Python 3.8以降で動作します。

import csv
import os
import sys
from datetime import datetime, timezone
from pathlib import Path

import requests

BASE_URL = "https://tiktok.evelode.com/searchVideo"
CSV_PATH = Path("tiktok_video_snapshots.csv")
FIELDS = [
    "collected_at", "aweme_id", "author", "description", "share_url",
    "play_count", "digg_count", "comment_count", "share_count",
]


def extract_items(payload):
    """Support the observed search response layouts."""
    data = payload.get("tiktok") or {}
    items = data.get("aweme_list") or []
    if items:
        return items

    found = []
    for result in data.get("search_item_list") or []:
        info = result.get("aweme_info")
        if info:
            found.append(info)
    return found


def main():
    key = os.environ.get("JSONSCRAPER_TIKTOK_LICENSE_KEY")
    if not key:
        raise SystemExit("Set JSONSCRAPER_TIKTOK_LICENSE_KEY first")
    if len(sys.argv) < 2:
        raise SystemExit('Usage: python collect.py "search phrase"')

    params = {
        "license_key": key,
        "keyword": sys.argv[1],
        "count": 20,
        "region": "US",
        "sort_by": "relevance",
        "date_posted": "this-week",
    }
    response = requests.get(BASE_URL, params=params, timeout=30)
    response.raise_for_status()
    payload = response.json()

    if payload.get("status") != "ok":
        raise RuntimeError("API returned a non-ok outer status")
    data = payload.get("tiktok") or {}
    items = extract_items(payload)
    collected_at = datetime.now(timezone.utc).isoformat()

    rows = []
    for item in items:
        stats = item.get("statistics") or {}
        author = item.get("author") or {}
        rows.append({
            "collected_at": collected_at,
            "aweme_id": item.get("aweme_id"),
            "author": author.get("unique_id") or author.get("nickname"),
            "description": item.get("desc"),
            "share_url": item.get("share_url"),
            "play_count": stats.get("play_count"),
            "digg_count": stats.get("digg_count"),
            "comment_count": stats.get("comment_count"),
            "share_count": stats.get("share_count"),
        })

    write_header = not CSV_PATH.exists()
    with CSV_PATH.open("a", newline="", encoding="utf-8") as file:
        writer = csv.DictWriter(file, fieldnames=FIELDS)
        if write_header:
            writer.writeheader()
        writer.writerows(rows)

    print("Saved", len(rows), "returned videos")
    print("has_more:", data.get("has_more"), "cursor:", data.get("cursor"))


if __name__ == "__main__":
    main()

たとえば、python collect.py "製品に関する検索語句"を実行します。キーはライブラリによってURLパラメーターに設定され、スクリプトからターミナルに出力されることはありません。リクエストURLにはキーが含まれるため、URL全体を公開ログに保存しないでください。本番環境ではシークレット管理ツールを使用し、スナップショットファイルへのアクセスを制限してください。

実行間の増加分を計算する

このスクリプトは前回の値を上書きせず、すべての観測結果を記録します。次の短い分析コードは、各動画について最新の2つのスナップショットを照合し、カウンターの差を出力します。2つのレコードのいずれかで指標の値が欠けている場合、結果は取得不可として扱います。

記事:生の再生数を比べずに、エンゲージメントが伸びているTikTok動画を見つける方法
概要:検索で見つけたTikTok動画の指標をCSVに保存し、次回の実行時に同じ動画の変化を計算するPythonの手順。
画像の役割:補助イラスト2 — 別の具体的な側面
セクション:実行間の増加分を計算する
ビジュアルの内容:TikTokのキーワード検索から返された動画へと続くワークフローを示すロシア語のインフォグラフィック
検索結果から、保存した2つのスナップショットの比較までのデータの流れ。© jsonscraper · AI生成イラスト
import csv
from collections import defaultdict
from pathlib import Path

rows_by_video = defaultdict(list)
with Path("tiktok_video_snapshots.csv").open(encoding="utf-8", newline="") as file:
    for row in csv.DictReader(file):
        if row["aweme_id"]:
            rows_by_video[row["aweme_id"]].append(row)

metrics = ("play_count", "digg_count", "comment_count", "share_count")
for video_id, snapshots in rows_by_video.items():
    snapshots.sort(key=lambda row: row["collected_at"])
    if len(snapshots) < 2:
        continue
    previous, latest = snapshots[-2], snapshots[-1]
    changes = {}
    for metric in metrics:
        old, new = previous[metric], latest[metric]
        changes[metric] = int(new) - int(old) if old and new else None
    print(video_id, changes, latest["share_url"])

差分は、保存した2つの値の引き算であり、一定の周期が保証された増加速度ではありません。実行間隔が異なる場合は、collected_atの差から経過時間を計算し、実際の期間に応じた増加分を比較してください。観測の間にカウンターが変化することがあります。保存したタイムスタンプを見れば、使用した値をいつ取得したか確認できます。

レポートを自動化して読み解く

日次レポートを作成するには、サーバーやCIのタスクスケジューラーに取得処理を登録し、検索語句を固定して、CSVに保存するか、行データをデータベースに読み込みます。検索結果に重複がある場合は、同じスナップショット内でaweme_idを使って重複を除去してください。履歴を管理する際は、正規化した列とともに元のJSONも保存すると、レポートのスキーマが変わったときに再処理しやすくなります。

表には動画のIDとURL、投稿者、説明文、取得時刻、指標ごとの差分を表示すると便利です。再生数の増加順に並べると拡散状況がわかり、コメント数やシェア数の増加を見ると、別の種類の反応を把握できます。各カウンターの意味は異なるため、明確なルールなしに単一のランキングへ集約しないでください。

スケジューラーからメール、表計算シート、社内チャンネルにレポートを送信することもできますが、その処理は利用者側のインフラで行います。上記の例が担うのはデータの取得と分析だけです。より多くの結果を取得するには、結果ページを順にたどり、カーソルを保存し、APIが次のページがないと通知した時点でループを終了します。検索カーソルはレスポンスに含まれる不透明な値なので、自分で計算しないでください。ページをすべてたどった場合でも、得られるのは返された検索結果であり、該当する投稿の完全な一覧が保証されるわけではありません。

実用上の成果は、再現可能な観測記録と、見つかった動画の変化をまとめた表です。確認の間に公開カウンターが変化した投稿を見つけ、内容を詳しく分析する担当者に個別のリンクを共有できます。製品の詳細とAPIへのアクセスについては、TikTok Scraper APIのページをご覧ください。

定期実行の前に確認すること

  • tiktokを処理する前に、外側のレスポンスステータスがokであることを確認してください。
  • 検索項目の2種類の構造に対応しているか確認してください。リストがない場合はエラーではなく、取得件数ゼロとして処理します。
  • 元の値とタイムスタンプを保存してください。指標が空の場合は、空のままにします。
  • スナップショットをわかりやすく比較できるよう、同一の検索語句とパラメーターを使用してください。設定を変更した場合は、レポートと併せて記録します。
  • 実行頻度、HTTPエラー、履歴のサイズを監視し、適用されるプラットフォームのルールとデータ処理要件を遵守してください。

つまり、観測結果を得るには、同じ検索を繰り返し、aweme_idで動画を識別し、保存した指標を時系列で比較すれば十分です。この方法で答えられるのは、「すでに見つかった動画のうち、2回の確認の間に公開カウンターが変化したものはどれか」という限定的で実務的な問いです。元データも、監査や追加処理のために引き続き利用できます。

人々

この記事にはまだ人物がリストされていません。

読み続けてくださいTikTokクリエイターのトピック分析:Python実践パイプライン
次の記事を読む

読んだ内容を実用的な連携へ

jsonscraperのソーシャルデータAPIを調べ、リクエストを試し、次のワークフローを構築しましょう。

APIを探す