jsonscraper

איך להשוות בין קריאייטיבים של מתחרים ב-TikTok באמצעות מדדים ציבוריים: צינור עבודה ב-Python

אספו תוצאות מכמה שאילתות חיפוש, הסירו כפילויות והשוו סרטונים לפי צפיות, לייקים ותגובות

מדיניות עריכה דיווח על שגיאה

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

הפתרון הוא לאסוף מדגם מוגבל וניתן לשחזור של סרטונים ציבוריים לפי מילות מפתח שנקבעו מראש, לשמור את ה-JSON המקורי ולבנות טבלה עם שדות אחידים. כך אפשר להשוות סרטונים במסגרת תהליך עבודה אחיד, במקום לערבב תצפיות אקראיות עם מסקנות על השוק. להלן מתווה לניטור מתחרים בהיקף קטן ב-Python באמצעות TikTok Scraper API של jsonscraper.

הגדירו תחילה את שאלת הניתוח

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

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

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

תכננו צינור נתונים קטן

חלקו את העבודה לארבעה שלבים: איסוף, שמירת התגובה הגולמית, נרמול וניתוח. האיסוף פונה ל-API עבור כל מילת מפתח שאושרה. שומרים את התגובה הגולמית במלואה כדי שאפשר יהיה לבדוק אותה שוב. הנרמול ממיר את מבנה ה-JSON המקונן לשורות בטבלה, והניתוח מחשב מדדים ומקבץ סרטונים לפי מילות מפתח או לפי פורמטים שסומנו ידנית.

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

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

מה תומך TikTok Scraper API

לחיפוש סרטונים לפי שאילתת טקסט, תיעוד jsonscraper מתאר נתיב GET בשם \/searchVideo בכתובת הבסיס https:\/\/tiktok.evelode.com. הפרמטר הנדרש הוא keyword; זמינים גם count, cursor, region, date_posted, sort_by ו-cache_timeout. בתיעוד מצוינות אפשרויות המיון most-liked, relevance ו-date-posted, ובין תקופות הפרסום: yesterday, this-week, this-month, last-3-months, last-6-months ו-all-time. בדקו את שמות הפרמטרים ואת תפקידיהם במדריך הנתיבים של TikTok.

המפתח מועבר בפרמטר השאילתה license_key. בסקריפט עבודה, שמרו אותו במשתנה סביבה בשם JSONSCRAPER_TIKTOK_LICENSE_KEY, ולא בקובץ המקור, בגיליון או ביומן ההרצה. בתגובה בדקו את status ברמה העליונה, ואז נתחו את האובייקט tiktok. בחיפוש, המבנה עשוי להכיל רשימה בשם aweme_list, וגם search_item_list, שבה פרטי הסרטון נמצאים בתוך aweme_info. הקוד שלהלן תומך בשתי הצורות.

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

דוגמה בסיסית ב-Python

הסקריפט שלהלן שולח בקשה אחת לכל מילת מפתח, שומר את התגובה המלאה בקובץ JSON ויוצר CSV לגיליון אלקטרוני או לעיבוד נוסף. הוא מיועד ל-Python 3.8 ומעלה ומשתמש בספרייה הסטנדרטית בלבד. הגדירו את משתנה הסביבה עם מפתח הרישיון לפני ההרצה. התאימו את רשימת מילות המפתח ואת מספר התוצאות לתרחיש שלכם.

import csv
import json
import os
import time
from datetime import datetime, timezone
from pathlib import Path
from urllib.parse import urlencode
from urllib.request import urlopen

BASE_URL = "https:\/\/tiktok.evelode.com\/searchVideo"
LICENSE_KEY = os.environ["JSONSCRAPER_TIKTOK_LICENSE_KEY"]
KEYWORDS = ["בקבוק תרמי", "בקבוק ספורט", "פתיחת אריזת בקבוק"]
REGION = "US"
COUNT = 20


def request_search(keyword):
    params = {
        "license_key": LICENSE_KEY,
        "keyword": keyword,
        "count": COUNT,
        "region": REGION,
        "sort_by": "relevance",
        "date_posted": "this-month",
    }
    url = BASE_URL + "?" + urlencode(params)
    with urlopen(url, timeout=60) as response:
        return json.loads(response.read().decode("utf-8"))


def extract_videos(payload):
    if payload.get("status") != "ok":
        raise RuntimeError("API returned a non-ok status")

    tiktok = payload.get("tiktok") or {}
    rows = []

    for item in tiktok.get("aweme_list") or []:
        if isinstance(item, dict):
            rows.append(item)

    for item in tiktok.get("search_item_list") or []:
        video = item.get("aweme_info") if isinstance(item, dict) else None
        if isinstance(video, dict):
            rows.append(video)

    return rows, tiktok


Path("raw").mkdir(exist_ok=True)
seen = set()
records = []

for keyword in KEYWORDS:
    payload = request_search(keyword)
    collected_at = datetime.now(timezone.utc).isoformat()
    safe_name = keyword.replace(" ", "_")
    raw_path = Path("raw") / (safe_name + ".json")
    raw_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")

    videos, tiktok = extract_videos(payload)
    for video in videos:
        video_id = video.get("aweme_id")
        if not video_id:
            continue
        dedupe_key = (keyword, video_id)
        if dedupe_key in seen:
            continue
        seen.add(dedupe_key)

        stats = video.get("statistics") or {}
        author = video.get("author") or {}
        records.append({
            "collected_at": collected_at,
            "keyword": keyword,
            "video_id": video_id,
            "url": video.get("share_url"),
            "created_at_epoch": video.get("create_time"),
            "description": video.get("desc"),
            "author": author.get("nickname"),
            "username": author.get("unique_id"),
            "views": stats.get("play_count"),
            "likes": stats.get("digg_count"),
            "comments": stats.get("comment_count"),
            "shares": stats.get("share_count"),
            "saves": stats.get("collect_count"),
            "cursor": tiktok.get("cursor"),
        })

    time.sleep(1)

fieldnames = [
    "collected_at", "keyword", "video_id", "url", "created_at_epoch",
    "description", "author", "username", "views", "likes", "comments",
    "shares", "saves", "cursor",
]
with open("tiktok_creatives.csv", "w", newline="", encoding="utf-8") as output:
    writer = csv.DictWriter(output, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerows(records)

print("Saved", len(records), "video rows to tiktok_creatives.csv")

הסקריפט שומר את מילת המפתח לצד הסרטון, וזה חשוב אם אותו סרטון נמצא באמצעות כמה שאילתות. כאן הסרת הכפילויות מתבצעת בתוך כל מילת מפתח, ולכן אותו מזהה יכול להופיע בשורה נפרדת עבור שאילתות שונות. כדי ליצור טבלה מאוחדת ללא חזרות, החליפו את המפתח (keyword, video_id) ב-video_id, וצברו את מילות המפתח ברשימה או בטבלת קשר נפרדת.

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

כך יוצרים טבלה שאפשר להשוות

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

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

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

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

הרצה חוזרת ומעקב אחר שינויים

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

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

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

איך להרחיב את תהליך העבודה

כאשר מדגם החיפוש רועש מדי, אפשר לעקוב בנפרד אחר פרופילים ציבוריים מסוימים או האשטגים. בתיעוד מופיעים הנתיבים \/getUserFeed ו-\/getHashtagFeed, עם פרמטרים לבקשה ולעימוד. אלה מדגמים אחרים, עם כללי המשך משלהם: לפיד של פרופיל משתמשים ב-max_cursor, ולהאשטג ב-cursor. הוסיפו אותם כמקורות נפרדים ושמרו את סוג המקור ואת הפרמטרים, כדי לא לערבב תוצאות של חיפוש לפי מילת מפתח עם פרסומים מפרופיל או מהאשטג.

לצוות שאין לו תשתית משלו, אפשר להעביר את קובץ ה-CSV ל-Google Sheets באמצעות API: התיעוד של Google Sheets API מתאר קריאה וכתיבה של ערכי תאים. צרו גיליונות נפרדים להרצות הגולמיות, לסרטונים המנורמלים ולסיכום. האפשרות הזאת נוחה לתיוג משותף; כאשר היקף ההיסטוריה כבר אינו נוח לניהול בגיליון, העבירו את השורות לאחסון SQL תוך שמירה על אותם שדות ומקור הנתונים.

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

מה תקבלו בסוף

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

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

אפשר לבדוק את נתיב החיפוש ואת הפרמטרים בתיעוד הרשמי של jsonscraper, ופרטים על השירות וגישה אליו זמינים בעמוד TikTok Scraper API. התחילו בכמה ביטויי חיפוש, שמרו תגובת ניסיון אחת ובדקו את המבנה שלה לפני הגדרת לוח זמנים.

People

No people listed for this article yet.

Keep readingאיך לזהות סימנים מוקדמים למגמות בטיקטוק: ניטור אוטומטי של תוצאות החיפוש
Read the next article

הפכו את מה שקראתם לאינטגרציה עובדת

גלו את ממשקי ה-API לנתונים חברתיים של jsonscraper, בדקו בקשות ובנו את תהליך העבודה הבא.

גלה API