マーケターがTikTokで、目的の製品について話す投稿者の動画を見つけても、その情報を確認可能な連絡先につなげるのは簡単ではありません。TikTokとIGで投稿者名が異なることもあれば、プロフィールが非公開だったり、その人とのつながりを確認できなかったりすることもあります。実用的な成果は、「すぐに使える見込み客」の自動リストではなく、確認用の表です。元動画、TikTokの投稿者、候補となるIGユーザー名、APIの応答、以降の確認状況を記録します。
以下では、この作業に使える最小限のPython手順を紹介します。公開動画をキーワードで検索し、取得できる投稿者情報を保存したうえで、確認すべき根拠のあるユーザー名がすでにある場合に限り、IGプロフィールを調べます。APIでユーザー名からプロフィール情報を取得できますが、2つのアカウントが同一人物のものだと自動的に判断することはできません。
自動化するのに適した作業
家庭用コーヒー器具を販売するチームが、飲み物の淹れ方を紹介する公開動画の投稿者を探しているとします。手動検索はコンテンツを見つける最初の段階で役立ちますが、繰り返し実施するとなると、どの動画が連絡先につながったのか、プロフィール名の出所は何か、何を確認したのかを記録し続けるのが難しくなります。

このパイプラインでは、TikTok動画の検索、観察できたデータの保存、候補となるIGプロフィールの確認という3つの作業を分けています。これにより、分析担当者はCSVファイル1つで候補ごとの情報の出所を確認できます。IGの項目を入力するのは、公開プロフィールの説明やリンクからユーザー名を見つけた後、または人が他の入手可能な資料を使って確認した後に限ってください。
この方法は、小規模で再現可能なリストを手動で評価したい代理店、調査チーム、社内マーケターに役立ちます。発見時のコンテキストを保ち、似た名前だけを根拠に同一人物だと断定することを防げます。
取得できる項目
文書化されているTikTokの/searchVideoルートでは、keywordが必須パラメーターです。また、count、date_posted、sort_by、region、cursorも指定できます。確認できた応答には、動画ID、説明、投稿日、リンク、投稿者情報、公開されているエンゲージメント指標が含まれています。実際の項目は異なる場合があるため、以下のコードでは安全に読み込み、値がない場合は空欄にします。
この手順では、IGの文書化されたGETルート/v1/user/by/usernameを、usernameパラメーターとともに使用します。応答には、ユーザー名、表示名、非公開・認証済みかどうか、投稿数、フォロワー数、フォロー数、プロフィールの自己紹介が含まれる場合があります。これらは担当者が確認し判断するための情報であり、投稿者を評価するスコアではありません。
TikTok APIの公式ドキュメントでは検索パラメーターを、IG APIのドキュメントではIGのメソッドとパラメーターを説明しています。jsonscraperのAPI定義にも、ルート、パラメーター名、確認できた応答形式が記載されています。ここで示した確認日は2026年10月25日です。
キーと候補リストを設定する
APIキーは、JSONSCRAPER_TIKTOK_LICENSE_KEYとJSONSCRAPER_INSTAGRAM_LICENSE_KEYという環境変数に保存してください。ソースコード、CSV、タスクログには含めないでください。リクエストライブラリをインストールするには、python -m pip install requestsを実行します。以下の例はPython 3.8以降を想定しています。
import csv
import os
import sys
from urllib.parse import urlencode
import requests
TIKTOK_KEY = os.environ.get("JSONSCRAPER_TIKTOK_LICENSE_KEY")
INSTAGRAM_KEY = os.environ.get("JSONSCRAPER_INSTAGRAM_LICENSE_KEY")
if not TIKTOK_KEY or not INSTAGRAM_KEY:
sys.exit("Set JSONSCRAPER_TIKTOK_LICENSE_KEY and JSONSCRAPER_INSTAGRAM_LICENSE_KEY")
def get_json(base_url, path, params):
response = requests.get(
f"{base_url}{path}",
params=params,
timeout=30,
)
response.raise_for_status()
return response.json()
def extract_videos(payload):
"""Handle both observed TikTok search result locations."""
if payload.get("status") != "ok":
raise RuntimeError(f"TikTok API status: {payload.get('status')}")
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")
if video:
videos.append(video)
unique = {}
for video in videos:
video_id = video.get("aweme_id")
if video_id:
unique[video_id] = video
return list(unique.values())
keyword = "домашний кофе"
tiktok_payload = get_json(
"https://tiktok.evelode.com",
"/searchVideo",
{
"license_key": TIKTOK_KEY,
"keyword": keyword,
"count": 20,
"date_posted": "this-month",
"sort_by": "relevance",
},
)
rows = []
for video in extract_videos(tiktok_payload):
author = video.get("author") or {}
stats = video.get("statistics") or {}
rows.append({
"tiktok_video_id": video.get("aweme_id", ""),
"tiktok_url": video.get("share_url", ""),
"video_description": video.get("desc", ""),
"created_at": video.get("create_time", ""),
"tiktok_username": author.get("unique_id", ""),
"tiktok_author_name": author.get("nickname", ""),
"tiktok_followers": author.get("follower_count", ""),
"views": stats.get("play_count", ""),
"likes": stats.get("digg_count", ""),
"instagram_username": "",
"instagram_status": "not checked",
"instagram_followers": "",
"instagram_is_private": "",
"manual_match_review": "required",
})
# Fill this dictionary only with usernames found separately
# and added after manually checking their source.
verified_instagram_usernames = {
# "tiktok_video_id": "instagram_username"
}
for row in rows:
username = verified_instagram_usernames.get(row["tiktok_video_id"])
if not username:
continue
ig_payload = get_json(
"https://ig.jsonscraper.com",
"/v1/user/by/username",
{
"license_key": INSTAGRAM_KEY,
"username": username,
},
)
if ig_payload.get("status") != "ok":
row["instagram_status"] = "api status: " + str(ig_payload.get("status"))
continue
profile = ig_payload.get("ig") or {}
row["instagram_username"] = profile.get("username", username)
row["instagram_status"] = "profile returned"
row["instagram_followers"] = profile.get("follower_count", "")
row["instagram_is_private"] = profile.get("is_private", "")
row["manual_match_review"] = "check relationship manually"
if rows:
with open("social_lead_checks.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=rows[0].keys())
writer.writeheader()
writer.writerows(rows)
else:
print("No video rows returned for this query.")
応答の2つの形式を扱う理由
TikTok検索の動画は、tiktok.aweme_listとtiktok.search_item_list[].aweme_infoという2か所に含まれる場合があります。確認した検索応答では、前者のリストが空でも、後者に項目が入っていることがありました。そのため、この例では両方の情報源をまとめ、aweme_idを使って重複を取り除きます。まず外側のstatusを確認し、その後にtiktokオブジェクトを読み込みます。

コードでは、実際に応答に含まれる項目だけを保存します。値が空欄の場合は、受け取ったオブジェクトにその項目がなかったことを意味し、指標がゼロだと解釈してはいけません。動画のリンクや説明も指標と一緒に保存すると、後で表を見直す際に元のコンテキストを失わずに済みます。
必要な場合に限ってページネーションを追加する
この例では1ページだけをリクエストし、返された項目だけを処理します。検索を続ける場合、ドキュメントでは動画検索用のcursorが定められており、その値は前の応答から取得します。cursorは不透明な値として扱い、独自に計算せず、そのまま渡してください。応答が続きのないことを示したとき、またはチームで決めた上限に達したときにループを停止します。ページネーションで取得結果を増やせますが、トピックに関するすべての投稿を網羅できるわけではありません。
自動取得を追加する前に、自分のキーで実際の応答を確認し、ページ数は控えめに設定してください。元のJSONは、正規化した行と一緒に、または実行日ごとに別途保存します。そうすれば、応答フィールドが変わったかどうかを調べたり、スキーマ変更時に収集データを再処理したりできます。
CSVを見込み客の評価に活用する
表では、動画リンク、説明、投稿者、入力済みのIGプロフィールの有無で行を絞り込めます。最初の確認には、「動画を発見」「IGのユーザー名を確認」「プロフィール応答あり」「アカウントの関連性を人が確認」「除外」といったシンプルなステータスが役立ちます。これらは確認の進捗を示すものであり、投稿者の品質や意図を表すものではありません。
再現可能なレポートが必要なら、スクリプトをスケジュール実行し、取得日を別の列に追加します。スナップショットを比較すれば、たとえばプロフィールのフォロワー数など、取得可能な項目が実行間にどう変化したかが分かります。TikTokとIGの指標は、プラットフォームと観測時刻を明記し、別々に保存してください。両者は異なる文脈に基づく、別々のAPI応答です。
処理量が増えた場合は、CSVを、プラットフォームと動画IDを複合的な主キーとするデータベースに置き換えます。元の検索語、収集時刻、未加工の応答を保存してください。Slackへの通知やCRMへの行の登録は、プロフィール間の関連性を人が確認した後に行い、名前が一致しただけですぐに実行しないでください。
解釈上の限界と安全な運用
キーワード検索で得られるのはAPIが返す検索結果であり、すべての投稿を網羅した一覧ではありません。再生数、いいね数、フォロワー数は、リクエスト時点のスナップショットです。作業リストの並べ替えや後の確認には使えますが、それだけで商業的な意図、オーディエンス、連絡への同意を確認することはできません。
プロフィール同士の関連性は、明確な公開情報で確認し、誰がいつ確認したかを記録してください。IGのユーザー名を、出所を確認できない外部の表から取得した場合は、「要確認」のステータスを残します。非公開プロフィールや取得できない情報は、それぞれ独立した確認結果として表示し、推測で空欄を埋めないでください。
作業環境のシークレット管理機能にキーを保存し、エクスポートへのアクセスを制限するとともに、調査目的に合った保存期間を設定してください。CRMに渡すのは、その後の手動作業に必要な項目だけにし、適用されるプラットフォームの規則とデータ処理要件を遵守します。
実行後に得られるもの
実行後には、見つかった動画、投稿者、取得可能な指標と、IG確認用の個別項目を含むCSVが作成されます。スクリプトは手動、CIでの定期実行、自動化プラットフォームのHTTPリクエストノードから実行できます。重要なのは、データの収集と整理を自動化しつつ、アカウント同士の関連性を確かめる手順は、人が確認できる形で残すことです。
ルートと利用可能なパラメーターを確認するには、TikTok Scraper APIとIG Scraper APIから始めてください。各製品ページにはリクエスト例とドキュメントへのリンクがあります。継続的な処理に組み込む前に、小規模なリクエストから始めましょう。