יוצר עשוי להיראות מתאים לקמפיין לפי הפרופיל שלו וכמה סרטונים מוצלחים, אבל הפיד העדכני שלו מספר סיפור חשוב יותר: האם הוא ממשיך לדבר בקביעות על הנושא הרצוי? בדיקה ידנית מתיישנת במהירות, וצפייה חד-פעמית עלולה להסתכם בבחירת הפרסומים הבולטים ביותר. לסוכנות או למותג עדיף לאסוף מדגם חוזר של סרטונים ציבוריים, לשמור את המצב במועד הבדיקה ולהעריך התאמה נושאית לפי אותם כללים בכל פעם.

להלן תהליך מעשי להערכת פיד ציבורי של יוצר TikTok. הוא משתמש ב-TikTok Scraper API של jsonscraper וב-Python: מקבל פרסומים דרך נתיב מתועד, שומר את ה-JSON המקורי, ממפה שדות מאומתים לטבלה ומחשב את שיעור הסרטונים המתאימים לנושא מוגדר. אם רוצים, אפשר להעביר את התיאורים למסווג טקסט כשלב נוסף, נפרד ומפוקח.
תחילה הגדירו מה נחשב «מתאים»
נניח שהצוות בוחר יוצר לקמפיין בנושא הכנת קפה בבית. מספר העוקבים והפופולריות של סרטונים מסוימים עשויים לסייע בתיאור החשיפה, אך כשלעצמם אינם עונים על השאלה עד כמה הפיד קשור לקפה. לצורך סינון ראשוני דרושים סימני תוכן: האם תיאור הסרטון מזכיר הכנת קפה, ציוד, מתכונים או ביקורות; כמה פרסומים בנושא נכללו בחלון התצפית שנקבע; ומהו שיעור הסרטונים הנושאיים מתוך אלה שנאספו.
לפני איסוף הנתונים, תעדו את הקריטריונים במילון קצר: למשל, «אספרסו», «מטחנת קפה», «לאטה», «חליטה». הוסיפו החרגות ומילים עמומות. «קפה» עשוי להופיע בבדיחה, בשילוב פרסומי או בהקשר מקרי, ולכן התאמה אוטומטית לטקסט היא תיוג ראשוני, לא הערכה סופית של היוצר. הפרידו לפחות בין שלושה מצבים: התאמה ברורה, התאמה אפשרית וסרטון לא רלוונטי.
יש להגדיר מראש גם את המדגם. למשל, אפשר לנתח את 20 הפרסומים האחרונים שהתקבלו בכל הרצה שבועית. זו הגדרה של הניטור שלכם, לא הבטחה שה-API יחזיר בדיוק כמות כזאת: הזמינות והרכב התוצאות נקבעים לפי התשובה לבקשה המסוימת. רשמו את מועד האיסוף, את מספר הפריטים שהתקבלו ואת פרמטרי הבקשה, כדי להשוות תמונות מצב בלי לערבב בין כללים שונים.
בקשה לפיד של יוצר
בתיעוד של jsonscraper, הנתיב GET /getUserFeed מקבל את הפרמטר החובה query — שם משתמש או כתובת URL של פרופיל. בין הפרמטרים האופציונליים מופיעים count, region, sort_type, with_pinned_posts ו-max_cursor. מפתח ה-API מועבר כ-license_key במחרוזת השאילתה; שמרו אותו במשתנה סביבה ולא בקוד המקור. פרטים על הנתיבים והפרמטרים מופיעים ב-תיעוד הרשמי של TikTok API.
בתשובה, בדקו תחילה את status החיצוני, ואז גשו לאובייקט tiktok. בפיד של משתמש, רשימת הפרסומים נמצאת ב-tiktok.aweme_list. בסכמה שנצפתה מופיעים מזהה סרטון, טקסט תיאור, מועד פרסום, מחבר, כתובת URL ואובייקט סטטיסטיקה. ייתכן ששדות מסוימים ייעדרו, ולכן המטפל צריך לשמור ערכים חסרים כריקים ולא להחליף אותם במספרים מומצאים.
הדוגמה המינימלית הבאה מיועדת ל-Python 3.8 ומעלה ולספריית requests. שמרו את המפתח במשתנה JSONSCRAPER_TIKTOK_LICENSE_KEY. הקוד מבצע בקשה אחת, בודק את תשובת HTTP ואת הסטטוס החיצוני של ה-API, כותב את ה-JSON המקורי ומדפיס רשומות מנורמלות.
import json
import os
from datetime import datetime, timezone
from pathlib import Path
import requests
API_KEY = os.environ["JSONSCRAPER_TIKTOK_LICENSE_KEY"]
PROFILE = "creator_username"
params = {
"license_key": API_KEY,
"query": PROFILE,
"count": 20,
"region": "US",
"sort_type": 0,
"with_pinned_posts": 0,
}
response = requests.get(
"https://tiktok.evelode.com/getUserFeed",
params=params,
timeout=30,
)
response.raise_for_status()
payload = response.json()
if payload.get("status") != "ok":
raise RuntimeError("TikTok API returned a non-ok status")
tiktok = payload.get("tiktok") or {}
items = tiktok.get("aweme_list") or []
stamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
Path("snapshots").mkdir(exist_ok=True)
Path(f"snapshots/{PROFILE}_{stamp}.json").write_text(
json.dumps(payload, ensure_ascii=False, indent=2),
encoding="utf-8",
)
rows = []
for item in items:
stats = item.get("statistics") or {}
author = item.get("author") or {}
rows.append({
"aweme_id": item.get("aweme_id"),
"created_at": item.get("create_time"),
"description": item.get("desc") or "",
"share_url": item.get("share_url"),
"creator": author.get("unique_id") or author.get("nickname"),
"play_count": stats.get("play_count"),
"digg_count": stats.get("digg_count"),
"comment_count": stats.get("comment_count"),
"share_count": stats.get("share_count"),
})
print(json.dumps(rows, ensure_ascii=False, indent=2))
הפרמטר sort_type מתועד עבור הנתיב הזה כ-0 לפיד עדכני וכ-1 לפיד פופולרי. בדוגמה נבחר מצב הפרסומים העדכניים, והסרטונים הנעוצים מוחרגים באמצעות with_pinned_posts=0, כדי שפוסט נעוץ ישן לא ייכלל במדגם של פרסומים חדשים. אם דרוש מצב אחר, שמרו את הפרמטר במטא-נתונים של תמונת המצב והשתמשו בו באופן אחיד בכל ההרצות.
עיבוד התשובה: מ-JSON לטבלה שניתן לשחזר
כדאי לשמור את התשובה המקורית לפני ביצוע טרנספורמציות. כך אפשר לבדוק מחדש את הנרמול, להבין מדוע שורה נותרה ריקה ולהתאים את המטפל אם משתנה זמינותם של שדות אופציונליים בתשובות. לצד קובץ ה-JSON, שמרו במאגר העבודה את מועד האיסוף ב-UTC, את הפרופיל שנשלח בבקשה, את הפרמטרים ואת גרסת הסקריפט. אל תכללו את מפתח ה-API בארכיון או ביומן.
בהרצות חוזרות, השתמשו ב-aweme_id כמזהה של פרסום, אם השדה קיים. הסרת כפילויות לפי המזהה הזה תמנע ספירה של אותו סרטון ככמה פרסומים כשהוא מתקבל שוב. עם זאת, שמרו תמונות מצב נפרדות של הסטטיסטיקה: ערכי צפיות ותגובות שייכים למועד התצפית, ואינם מאפיינים קבועים של הסרטון. אם שדה סטטיסטיקה חסר, השאירו אותו ריק והוציאו את הרשומה מחישוב המדד המתאים.
זמן הפרסום בסכמה מסומן כ-create_time. עבור טבלת האנליטיקה, המירו אותו לתאריך ושמרו גם את הערך המקורי וגם זמן UTC מנורמל. לפני החישוב, בדקו כמה רשומות אמיתיות מהתשובה שהתקבלה כדי לוודא את סוג הנתון והיחידות הצפויים. בדיקה זו חשובה במיוחד לבניית גרפים לאורך זמן: טעות בהמרת הזמן מעבירה פרסומים בין ימים ופוגעת בהשוואה השבועית.
אפשר לבנות מסווג נושאי בסיסי ללא מודל: לנרמל את הטקסט, לחפש בו ביטויי מפתח מוגדרים ולסמן התאמות. לסיווג מועיל יותר, הכינו אוסף תיאורים שנבדקו ידנית וכללים למקרים גבוליים. לאחר מכן השוו את מסנן המילים הפשוט לתוויות שקבע אדם: בדקו אילו ביטויים יוצרים התאמות שגויות ועדכנו את המילון. כך נוצר קו בסיס ברור, שאפשר להעריך מולו שימוש עתידי בבינה מלאכותית.
import re
KEYWORDS = (
"кофе", "эспрессо", "кофемолка", "латте", "заваривание",
)
def normalize(text):
text = (text or "").casefold()
return re.sub(r"\s+", " ", text).strip()
def classify(description):
text = normalize(description)
matches = [word for word in KEYWORDS if word in text]
return {
"topic_match": bool(matches),
"matched_terms": matches,
}
for row in rows:
row.update(classify(row["description"]))
מילת מפתח בתיאור עשויה להיות אות שימושי, אך המסווג צריך להחזיר סיבה שניתן להסביר: את רשימת המונחים שנמצאו, ולא רק תווית «כן/לא». עבור מודלי שפה, השתמשו בהנחיה מובנית: העבירו תיאור של סרטון ורשימה קבועה של קטגוריות, ובקשו להחזיר קטגוריה, נימוק קצר ורמת ביטחון. שמרו את הטקסט המקורי ואת תשובת המודל בנפרד. אדם צריך לבדוק לפי קישורים לפרסומים החלטות שמשפיעות על תקציב או על בחירת שותף.
חשבו מדדים עם מכנה ברור
לדוח פשוט מתאימים שיעור הסרטונים הנושאיים ותדירות הפרסום. שיעור הסרטונים הוא מספר הסרטונים שאומתה התאמתם לנושא, חלקי מספר הסרטונים שאפשר היה לסווג. הציגו תמיד את שני המספרים: למשל, «7 מתוך 18 תיאורים שנבדקו». כך התוצאה מובנת, ואפשר לשים לב מתי האחוז מבוסס על מדגם קטן מדי.
אפשר לבטא תדירות פרסום כמספר הסרטונים שהתקבלו בתקופה קבועה, למשל ב-30 הימים האחרונים. הגדירו את גבולות התקופה לפי מועד האיסוף ותאריכי הפרסום. באיסופים שבועיים, שמרו את התוצאה של כל הרצה ולא רק את השורה המצטברת המעודכנת: כך אפשר לראות שינויים בנושא ובפעילות. אל תתייחסו למספר הפריטים שנאספו כאל ארכיון מלא של פרסומי היוצר — נתחו את המדגם שהתקבל בפועל וציינו במפורש את כלל הבחירה שלו.
נוח להשתמש בנתוני צפיות, לייקים, תגובות ושיתופים כמידע הקשרי לכל סרטון. יש להשוות ערכים מוחלטים בזהירות: ייתכן שלפרסום מוקדם יותר היה זמן רב יותר לצבור תגובות. כדי להשוות בתוך אותו פרופיל, תעדו את מועד האיסוף בכל פעם ובחנו את השינוי באותו סרטון בין תמונות מצב. אל תכנו את ההפרש בין שתי תמונות מצב «קצב צמיחה» אם המרווח והזמינות של המדידות לא תועדו.
רשומה מסכמת שימושית לכל פרופיל כוללת את מועד האיסוף, הפרמטרים שנבחרו, מספר הפרסומים שהתקבלו, מספר התיאורים שסווגו, מספר ההתאמות הנושאיות, רשימת כתובות URL לדוגמאות והערה קצרה על מקרים עמומים. טבלה כזאת מאפשרת לעובד לבדוק את המסקנה ולאנליסט אחר לשחזר את השיטה בפרופיל הבא.
דפדוף בעמודים ותזמון
אם המדגם דורש עמוד נוסף, התיעוד של פיד הפרופיל משתמש ב-max_cursor שהתקבל בתשובה הקודמת. העבירו אותו בלי לשנותו: הסמן הוא ערך אטום שיש לשמור ולהחזיר ל-API. בדקו גם את has_more בתשובה אם מתכוונים לבקש עמוד נוסף. הגבילו את מספר העמודים או את התקציב הכולל של הבקשות, כדי שהאיסוף יסתיים באופן צפוי.
cursor = None
all_items = []
max_pages = 3
for _ in range(max_pages):
page_params = dict(params)
if cursor is not None:
page_params["max_cursor"] = cursor
page_response = requests.get(
"https://tiktok.evelode.com/getUserFeed",
params=page_params,
timeout=30,
)
page_response.raise_for_status()
page_payload = page_response.json()
if page_payload.get("status") != "ok":
raise RuntimeError("TikTok API returned a non-ok status")
page = page_payload.get("tiktok") or {}
all_items.extend(page.get("aweme_list") or [])
if not page.get("has_more"):
break
cursor = page.get("max_cursor")
if cursor is None:
break
בחרו את תדירות ההרצה בהתאם למשימה: להערכה ראשונית מספיקה הרצה ידנית; עבור רשימת יוצרים, לוח זמנים שבועי עשוי לזהות שינויים בלי לבצע סקרים רציפים. אפשר להריץ באמצעות cron, משימת CI או מתזמר. הסכמה פשוטה: לקבל פרופילים מטבלה, לבצע בקשות עם הגבלת מקביליות, לשמור תמונות מצב, לבדוק את שיעור התשובות המוצלחות ולשלוח סיכום לטבלת עבודה. לאחר שגיאה זמנית, נסו שוב מספר מוגבל של פעמים ובהשהיה; שמרו בנפרד שגיאות בבקשות מאומתות כדי לבדוק את המפתח ואת ההגדרות.
היכן בינה מלאכותית מתאימה והיכן נדרשת בדיקה
בינה מלאכותית מועילה לסיווג תיאורים הכוללים סלנג, כמה שפות או ניסוחים שאינם מכילים מילת מפתח מדויקת. תחילה הגדירו רשימה סגורה של קטגוריות ובקשו מהמודל להסתמך רק על טקסט התיאור. לאחר מכן מדדו את האיכות במדגם קטן שתויג ידנית: השוו את קטגוריות המודל להחלטות של עורך, ובחנו בנפרד שגיאות ומקרים עמומים. עדיף לכלול בדוח את שיעור ההתאמה בין סיווג המודל לתוויות הידניות ואת מספר הדוגמאות שנבדקו, ולא ציון כללי שאי אפשר לפרש.
אל תטילו על המודל את המשימה «בחר את היוצר הטוב ביותר» בלי קריטריונים. במקום זאת, חלקו את התהליך למאפיינים מדידים: שיעור התאמה נושאית, סדירות, דוגמאות לסרטונים רלוונטיים וטווח התגובות הציבוריות. המודל יכול לסכם בקצרה את השדות האלה ולציין קישורים לראיות; ההחלטה הסופית נשארת בידי הצוות, שמתחשב במתכונת הקמפיין, בקהל ובתיאום עם היוצר.
אם הניתוח עוסק בשילובים פרסומיים, בדקו בנפרד את גילוי הקשר של היוצר עם המותג בפרסומים עצמם ואת הדרישות החלות. המדריך של ועדת הסחר הפדרלית בארצות הברית מסביר שיש לחשוף קשר למותג באופן ברור לצד ההמלצה; עם זאת, ביוגרפיה בפרופיל או חלק מוסתר של הטקסט עלולים לא להספיק כדי להודיע לקהל באופן בולט. ראו את הנחיות FTC ליוצרי תוכן ברשתות חברתיות. ניטור נתונים ציבוריים מסייע לאסוף חומר לבדיקה, אך הערכת עמידה בכללים דורשת הקשר של הפוסט והקמפיין המסוימים.
מה מתקבל בסוף
לאחר הגדרת צינור העבודה, הצוות מקבל תמונות מצב מתוארכות של פיד ציבורי, טבלת פרסומים עם תיאורים ומדדים זמינים, וכן חישוב חוזר של שיעור התוכן הנושאי. אפשר להשתמש בהם כדי לסנן פרופילים להמשך בדיקה במהירות רבה יותר, לזהות שינוי בנושאים ולתעד את הסיבות להערכה. השיטה ניתנת לבדיקה: ה-JSON המקורי, פרמטרי הבקשה, כללי הסיווג והקישורים לסרטונים מאפשרים לעקוב אחר הדרך מהנתונים למסקנה.
לבדיקה ראשונית, הריצו את הסקריפט על פרופיל אחד, שמרו את התשובה הגולמית ובדקו ידנית כמה סיווגים. לאחר מכן קבעו מילון נושאים, כללי מדגם ומתכונת דוח. כאשר התוצאה תהיה ניתנת לשחזור, הוסיפו תזמון ורשימת פרופילים. תיאורי הנתיבים והפרמטרים מופיעים ב-תיעוד ה-API, וסקירת המוצר ואפשרויות האינטגרציה הזמינות מופיעות בעמוד TikTok Scraper API.
רשימת בדיקה מעשית לפני ההרצה
- תעדו את נושא הקמפיין, את מילון המונחים הכלולים ואת הדוגמאות למקרים גבוליים.
- קבעו את חלון המדגם, את ערך
count, את שיטת המיון ואת ההגדרה של פרסומים נעוצים. - שמרו את ה-JSON המקורי, את מועד האיסוף ואת הפרמטרים בנפרד ממפתח סודי.
- השתמשו ב-
aweme_idלהסרת כפילויות, אם המזהה קיים. - הבחינו בין ערך חסר לאפס ואל תחשבו ממוצע של מדדים בלי הצדקה ברורה.
- הציגו את גודל המדגם לצד שיעור התוכן הנושאי והוסיפו קישורים לדוגמאות.
- בדקו סיווג של בינה מלאכותית במדגם ידני לפני השימוש בו בהחלטות על קמפיין.
- עדכנו את ההערכה לפי לוח זמנים והשוו תמונות מצב שנאספו לפי כללים זהים.