마케터는 원하는 제품을 이야기하는 작성자의 TikTok 동영상을 찾을 수 있지만, 이런 신호를 검증 가능한 연락처로 연결하기는 더 어렵습니다. TikTok과 IG에서 작성자 이름이 다를 수 있고, 프로필이 비공개이거나 두 계정이 같은 사람의 것이라는 확인된 연결이 전혀 없을 수도 있습니다. 실용적인 결과물은 ‘확정된 리드’의 자동 목록이 아니라 검토 기록입니다. 여기에는 원본 동영상, TikTok 작성자, 추정 IG 사용자 이름, API 응답, 후속 검토 상태가 담깁니다.
아래는 이 작업을 위한 기본적인 Python 프로세스입니다. 키워드로 공개 동영상을 검색하고 확인할 수 있는 작성자 정보를 추출한 뒤, 검토할 근거가 있는 IG 사용자 이름이 이미 있는 경우에만 프로필을 확인합니다. API는 사용자 이름으로 프로필 정보를 가져올 수 있지만, 두 계정이 같은 사람에게 속하는지 자동으로 판별하지는 않습니다.
자동화할 결과 정하기
홈 커피 장비를 판매하는 팀이 음료를 만드는 공개 동영상의 작성자를 찾는다고 가정해 보세요. 수동 검색은 콘텐츠를 처음 파악하는 데 유용하지만, 반복해서 진행하다 보면 어떤 동영상에서 연락처를 찾았는지, 프로필 이름의 출처가 무엇인지, 실제로 어떤 항목을 확인했는지 기록하기 어렵습니다.

파이프라인은 동영상 검색, 관찰한 데이터 저장, 추정 IG 프로필 확인의 세 단계로 나뉩니다. 덕분에 분석가는 후보별 출처를 따라갈 수 있는 CSV 파일 하나를 열어볼 수 있습니다. 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 또는 작업 로그에 넣지 마세요. requests 라이브러리는 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",
})
# Заполняйте этот словарь только username, найденными отдельно
# и внесёнными после ручной проверки источника.
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.")
응답의 두 가지 구조를 처리하는 이유
TikTok 검색 결과의 동영상은 tiktok.aweme_list와 tiktok.search_item_list[].aweme_info 두 곳에서 나타날 수 있습니다. 확인된 검색 응답에서는 첫 번째 목록이 비어 있고 두 번째 목록에만 항목이 있는 경우가 있었습니다. 따라서 이 예시는 두 위치의 결과를 합치고 aweme_id를 기준으로 중복을 제거합니다. 먼저 최상위 status를 확인한 뒤 tiktok 객체를 읽습니다.

코드는 실제 응답에 있는 필드만 저장합니다. 값이 비어 있으면 해당 항목이 응답 객체에 없었다는 뜻이며, 이를 0으로 해석해서는 안 됩니다. 나중에 표를 검토할 때 원래 맥락이 사라지지 않도록, 지표와 함께 동영상 링크와 설명도 보관하는 것이 좋습니다.
필요할 때만 페이지네이션 추가하기
이 예시는 한 페이지를 요청하고 반환된 항목만 처리합니다. 검색을 계속하려면 문서에 따라 동영상 검색의 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부터 살펴보세요. 제품 페이지에서 요청 예시와 문서 링크를 확인할 수 있습니다. 수집을 상시 프로세스에 통합하기 전에 작은 요청부터 시작하세요.