jsonscraper

PythonでTikTok検索結果をアーカイブする方法

キーワード検索へのAPI応答を保存し、投稿を確認して、取得日ごとの利用可能な指標を比較します。

編集方針 誤りを報告する

キャンペーン開始後、選んだキーワードで検索したときに、どのような公開動画が表示されるかをチームで確認したい場合があります。手作業での検索は、数日後に同じ条件で再現し、比較するのが困難です。小規模な収集スクリプトを定期実行し、取得日時と検索語を付けて応答をアーカイブすれば、アナリストが記録を確認し、独自の集計を作成できます。

記事:PythonでTikTok検索結果をアーカイブする方法
概要:TikTokの公開動画を毎日アーカイブする実践的な方法。文書化されたjsonscraperのエンドポイントにリクエストし、元のJSON応答を保存して、サンプルデータを確認してから正規化します。
画像の役割:カバー — 中心となるアイデア
セクション:
ビジュアルの題材:日付と検索語のラベルが付いたJSONファイルが、TikTok動画のトレンドグラフを含むコンパクトな分析表へ流れ込む、データパイプラインを図式化した静物画。人物は含まない。
© jsonscraper · AI生成イラスト

このガイドでは、固定した検索語で検索結果を保存するPythonのアーカイブ用パイプラインを紹介します。個別のハッシュタグやアカウントを監視するのとは異なり、比較の鍵は同じ検索語を繰り返し使い、応答ごとに個別のスナップショットを保存することです。jsonscraperのTikTok Scraper APIのページには、ベースURLとルート GET /searchVideo が記載されています。このルートのドキュメントでは、検索語を必須パラメーター keyword で渡します。

目的と測定範囲

マーケターが毎日、製品名、カテゴリ、顧客の課題を表すフレーズなど、固定した複数の検索語で検索結果を収集したいとします。システムは検索ごとに取得時刻とAPI応答を保存します。応答例を確認した後で、動画IDや公開カウンターなど、実際にJSONに含まれているフィールドがあれば正規化を追加できます。

このアーカイブが答えるのは、「保存した検索語で、この実行時にどのレコードが返されたか」という具体的な問いです。応答に指標が含まれていれば、繰り返し観測することで、異なる時点に記録された値の差を確認できます。この差は観測したスナップショットとその間隔に関するものです。比較する際は、両方の取得時刻と同じフィールドを保存してください。

リクエストと応答は一緒に保存します。結果の内容は、特定の検索語と取得時刻に結び付いています。そのため、このアーカイブは選択した検索語の検索結果を追跡するのに役立ちますが、TikTok上のすべてのコンテンツを網羅するものではありません。ID、元の応答、タイムスタンプがあれば、後続の表の各行がどこから来たのかを確認できます。

ルートとパラメーターを確認する

TikTok APIのルート一覧には、ベースURL https://tiktok.evelode.com と GET /searchVideo が記載されています。最新のAPI仕様では、検索に必須のパラメーターとして keyword が挙げられています。任意パラメーターには cursor、count、cache_timeout、date_posted、sort_by、region があります。認証には license_key を渡します。ルートについてはPython SDKのドキュメントでも確認できます。

count と date_posted は、応答の件数や期間フィルターの指定に役立ちます。sort_by には、ドキュメントに記載された most-liked、relevance、date-posted を指定できます。ページネーションを使う場合は、前の応答で得た cursor を不透明な値として渡し、自分で計算しないでください。日次アーカイブを比較可能にするため、リクエストパラメーターと独自コードのバージョンもデータと一緒に保存します。

以下の例では、テスト実行用に小さな count 値を使い、地域を US に固定しています。毎日の収集を始める前に、リクエストを1件実行し、HTTPステータスとJSONの構造を確認してください。応答スキーマでは、見つかった動画が tiktok.aweme_list に含まれる場合と、動画オブジェクトが aweme_info に格納された tiktok.search_item_list に含まれる場合があります。コードは、観測された両方の形式に対応します。

プロジェクトを準備する

仮想環境を作成し、requests をインストールします。

python -m venv .venv
source .venv/bin/activate
pip install requests

PowerShellでは、.venv\Scripts\Activate.ps1 で環境を有効にします。キーと検索語の一覧は環境変数で設定します。TikTok APIには、ドキュメントに記載された環境変数名 JSONSCRAPER_TIKTOK_LICENSE_KEY を使います。

export JSONSCRAPER_TIKTOK_LICENSE_KEY="あなたのキー"
export TIKTOK_QUERIES="製品名,商品カテゴリ,顧客の課題"

スナップショットを収集して保存する

この例では、文書化されたルートに各検索語で1回ずつリクエストを送り、元のJSON、取得時刻、使用したパラメーターを保存します。ファイル名には日付と検索語が含まれます。キーは環境変数に保存し、アーカイブには含めません。

import json
import os
import re
import time
from datetime import datetime, timezone
from pathlib import Path

import requests

BASE_URL = "https://tiktok.evelode.com"
ENDPOINT = "/searchVideo"
LICENSE_KEY = os.environ["JSONSCRAPER_TIKTOK_LICENSE_KEY"]
QUERIES = [
    item.strip()
    for item in os.environ["TIKTOK_QUERIES"].split(",")
    if item.strip()
]
OUT = Path("data")
OUT.mkdir(exist_ok=True)


def safe_name(text):
    cleaned = re.sub(r"[^a-zA-Z0-9_-]+", "_", text).strip("_")
    return cleaned[:80] or "query"


def fetch(query):
    params = {
        "license_key": LICENSE_KEY,
        "keyword": query,
        "count": 10,
        "region": "US",
    }
    response = requests.get(
        BASE_URL + ENDPOINT,
        params=params,
        timeout=60,
    )
    response.raise_for_status()
    payload = response.json()

    if payload.get("status") != "ok":
        raise RuntimeError("APIがok以外のステータスを返しました")

    return payload


def extract_videos(payload):
    tiktok = payload.get("tiktok") or {}
    videos = list(tiktok.get("aweme_list") or [])
    for item in tiktok.get("search_item_list") or []:
        video = item.get("aweme_info") or {}
        if video:
            videos.append(video)
    return videos


for query in QUERIES:
    collected_at = datetime.now(timezone.utc).isoformat()
    payload = fetch(query)
    record = {
        "collected_at": collected_at,
        "query": query,
        "request": {
            "endpoint": ENDPOINT,
            "keyword": query,
            "count": 10,
            "region": "US",
        },
        "videos_found": len(extract_videos(payload)),
        "payload": payload,
    }
    filename = OUT / f"{collected_at[:10]}_{safe_name(query)}.json"
    filename.write_text(
        json.dumps(record, ensure_ascii=False, indent=2),
        encoding="utf-8",
    )
    print(f"検索語の応答を保存しました: {query}")
    time.sleep(1)

print(f"保存した応答数: {len(QUERIES)}")

この最小構成の収集スクリプトは、count=10 で検索語ごとに1件のリクエストを送ります。より広く収集するには、cursor によるページネーションを追加してください。APIが次の結果があると示す間、応答のカーソル値を次のリクエストに渡し、各応答を個別に記録します。カーソルと結果件数は、それぞれの取得処理を特定する情報です。保存されたJSONを使えば、各リクエストで実際に何が返されたのかを後から確認できます。

この例では外側の status を確認してから、tiktok オブジェクトを読み込みます。aweme_list の要素に加え、存在する場合は search_item_list[].aweme_info の要素も収集します。動画レコードにはID、説明、投稿者、リンク、統計情報などが含まれる可能性がありますが、個々のフィールドが欠けている場合もあります。そのため、応答全体を保存し、正規化の際には各フィールドの有無を確認してください。

1秒の間隔は、このスクリプト内でリクエスト間に設けた待機時間であり、サービスの制限について述べたものではありません。アクセス条件とドキュメントに従って、頻度と再試行を設定してください。検索では cache_timeout パラメーターが文書化されています。仕様によると、秒単位でキャッシュ期間を指定でき、値を0にするとキャッシュが無効になります。この動作が用途に合う場合は、リクエストに追加してください。

実際の応答に基づいて正規化する

初回実行後、保存したファイルを開き、payload の構造を調べます。例の extract_videos 関数は、応答内の動画が見つかる、ドキュメントに記載された2つの形式から要素を収集します。分析に必要なフィールドの正確なキーを確認してください。特定のレコードにフィールドが存在しない場合は、推測した数値を入れず、欠損値として扱います。

後続の処理では、見つかったオブジェクトごとに1行を作成し、collected_at と query を追加すると便利です。確認済みのフィールドをCSVやデータベースに保存し、元のJSONはアーカイブに残しておきます。この組み合わせなら、使いやすい表を作りながら、各レコードの出所も確認できます。

APIが動画IDを返す場合は、そのIDを使って、異なる実行で同じ動画を観測した記録を関連付けます。過去の記録を上書きせず、各観測を個別に保存してください。安定したIDがない場合は、どの属性でレコードを照合できるかをまず確認し、説明文だけで必ず一致すると見なさないでください。

スナップショットを比較してレポートを作成する

正規化した後、確認済みのIDでレコードをグループ化し、取得時刻順に並べます。カウンターのフィールドなら、連続する2つの値の差を通常のコードで計算できます。たとえば、12,400から18,900への変化は、スナップショット間でカウンターの値が6,500増えたことを意味します。読者が計算を検証できるよう、レポートには観測日と元のフィールドを記載してください。

最終的な表には、検索語、投稿ID、取得時刻、応答から選んだフィールドを含めると便利です。検索語ごとに集計し、確認済みのカウンター1つで並べ替えることもできます。これにより、チームが後で確認できる、返されたレコードの検証可能な一覧ができます。表や通知の作成は、実際のスキーマを調べた後に別の手順として実装してください。

まずJSONファイルをローカルに保存します。収集が定期化したら、正規化した行をPostgreSQLや分析用データウェアハウスに移し、元の応答はファイル名に日付と検索語を含めてオブジェクトストレージに保存します。パーサーを調整する際、元データが残っていれば、APIに再度問い合わせずに過去のデータで処理をやり直せます。

スケジュールに従って収集する

日次アーカイブには、cronや利用環境で使用できる別のスケジューラーからスクリプトを実行します。たとえば、環境変数でキーと検索語を渡して、Pythonファイルを1日1回実行できます。定期運用の前に、まずリクエストを1件、次に検索語の一覧全体を確認してから、スケジュールを設定してください。

安定した実行のため、リクエストごとのステータスを保存し、一時的なエラーでの再試行回数を制限します。また、どれか1つの検索語で失敗した場合は、収集が不完全であることを記録してください。エラーメッセージにキーを含めないでください。日付と検索語名でファイルを分けておけば、再実行時に以前のスナップショットを上書きせずに済みます。

用途とリクエスト数に応じて頻度を選んでください。日次の確認なら1日1回の実行で十分です。チームが日中の変化を重視する場合は、より頻繁な収集が役立つことがあります。少数の検索語から始め、返される結果が有用かを確認してから、アクセス条件とデータ利用ルールの範囲内で対象を広げてください。

AIでテーマ別に分類する

応答スキーマを確認した後、選んだテキストフィールドをモデルに渡して、あらかじめ定義したテーマごとに説明文を分類したり、短い要約の下書きを作成したりできます。分類結果と一緒に、元の投稿ID、検索語、カテゴリの根拠となったテキストの一部を保存してください。そうすれば、アナリストはモデルの出力から元のレコードをたどれます。

数値の差分計算、並べ替え、重複排除は通常のコードで行います。モデルはテキストの処理やレポートの文章作成に使い、カウンターとタイムスタンプには保存した応答の値を使ってください。こうした作業の分担により、各結果の根拠が明確になります。

自動分類の一部を手動で確認し、修正内容をテスト用の例として保存してください。異なる種類の投稿が繰り返し同じグループに分類される場合は、カテゴリの定義を見直し、再度確認します。このプロセスにより、実際の用途における分類品質を評価できます。

まとめ:再現可能なアーカイブと検証可能な集計

keyword パラメーターを使った文書化済みの検索を実行すると、チームは、どの検索語をいつ使い、APIがそれぞれにどのデータを返したのかを記録できます。それを基に結果の表を作成し、確認済みのフィールドをスナップショット間で比較して、見つかった投稿を手作業で分析するための一覧を用意できます。

検索を1件だけテストし、次に検索語の一覧とスケジュールを設定します。TikTok Scraper APIの説明には、ベースURLとルート一覧が記載されています。/searchVideo のパラメーターと応答形式は、API仕様で確認できます。確認済みの応答をアーカイブすれば、固定した検索語に基づく、再現可能な分析の土台を作れます。

People

No people listed for this article yet.

Keep readingTikTokクリエイターのトピック分析:Python実践パイプライン
Read the next article

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

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

APIを探す