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

להלן תהליך עבודה שימושי לאיש או אשת שיווק, לאנליסטים או למפתחים שצריכים להשוות מדי שבוע בין חשבונות ציבוריים באותו תחום. לקבלת הנתונים נעשה שימוש ב-IG Scraper API של jsonscraper; Python אחראית על תזמון, נרמול ושמירת ההיסטוריה. זהו המשך לנושא ניטור פרופילים ופרסומים של מתחרים, עם דגש על מודל תצפיות אחיד שמתאים לדוח השוואתי.
תחילה הגדירו מה בדיוק להשוות
המשימה מנוסחת לעיתים קרובות באופן רחב: «למצוא יוצרים יעילים». כדי לבנות ניטור שימושי מבחינה טכנית, כדאי לצמצם אותה לשאלות מדידות: באיזו תדירות מתפרסמים פוסטים, אילו פורמטים מופיעים, כמה לייקים ותגובות ציבוריים ניתן לראות בעת הבדיקה, וכיצד המספרים האלה משתנים לאחר הפרסום. מערך כזה מסייע לבחור חשבונות לבדיקה ידנית או להכין סקירה השוואתית.
מוני התגובות הציבוריים הם תמונת מצב ברגע הבקשה. לכן, ההחלטה הארכיטקטונית המרכזית אינה מודל מורכב אלא שמירת זמן האיסוף לצד הערך. אם בכל לילה אוספים מידע על אותה מדיה ודורסים את השורה הקודמת, ההיסטוריה הדרושה לחישוב הגידול נעלמת. במקום זאת, שמרו תצפיות באופן בלתי משתנה: שורה אחת לכל פרסום ולכל מועד איסוף.
יש להגביל את ההשוואה לתקופות זהות ולפרסומים בני-השוואה. לדוגמה, אפשר לבחון פרסומים שהתגלו לראשונה באותו חודש קלנדרי, או להביא בחשבון את גיל הפרסום בכל תמונת מצב. אחרת, סרטון מאתמול ייראה חלש מפוסט ישן רק משום שהיה לו פחות זמן לצבור תגובות.
צינור העבודה: בקשה, נרמול, היסטוריה
בגרסה הבסיסית, התהליך כולל ארבעה שלבים: קבלת רשימת המדיה הציבורית של הפרופילים שנבחרו, התאמת התשובה לסכמה אחידה, כתיבת השורות למאגר ויצירת דוח לפי לוח זמנים. דף IG Scraper API מציג את כתובת הבסיס ואת מפת נקודות הקצה, כולל נתיב משתמש לשליפת פרסומים במנות. בדקו את הפרמטרים של כל נתיב ואת דוגמאות התשובות ב-אוסף Postman לפני האינטגרציה.
כתובת הבסיס של ה-API היא https:\/\/ig.jsonscraper.com. לצורך בדיקה ראשונית, התיעוד מציג בקשת פרופיל לפי שם משתמש: GET \/v1\/user\/by\/username עם הפרמטרים username, license_key ו-cache_timeout בדוגמה שפורסמה. לקבלת פרסומים מצוין הנתיב GET \/v1\/user\/medias\/chunk. יש לקחת את הארגומנטים המדויקים שלו, את שדות ההמשך ואת מבנה התשובה מהתיעוד של הבקשה הזאת עצמה; אל תעבירו סכמה מנתיב אחד לאחר.
import os
import requests
BASE = "https:\/\/ig.jsonscraper.com"
KEY = os.environ["JSONSCRAPER_LICENSE_KEY"]
def get_profile(username: str) -> dict:
response = requests.get(
f"{BASE}\/v1\/user\/by\/username",
params={
"username": username,
"license_key": KEY,
"cache_timeout": 60,
},
timeout=30,
)
response.raise_for_status()
return response.json()
print(get_profile("example_account"))
הדוגמה הקצרה הזאת חוזרת על נתיב הפרופיל המתועד ומראה כיצד להעביר פרמטרים באמצעות HTTP GET. הערך cache_timeout=60 מופיע בדוגמה שפורסמה; השתמשו בו רק בנתיבים שתומכים בפרמטר, ובדקו את הפרטים בתיעוד. יש לשמור את המפתח במשתנה סביבה, ולא בקוד או באפליקציית דפדפן.
הוסיפו שליפה של פרסומים
לאחר בדיקת הפרופיל, הוסיפו בקשה לרשימת המדיה. בדף ה-API מופיע הנתיב GET \/v1\/user\/medias\/chunk; כדי לעבד את התוצאה, השתמשו בלוגיקה לשליפת מנות המתועדת. את שמות הפרמטרים ואת התנאי לסיום העימוד יש לקחת מהתיאור העדכני של הבקשה הזאת ב-Postman, ולא לנחש לפי שם הנתיב.
להלן שלד לקריאה בשכבת התעבורה, ולא חוזה מוכן של נקודת הקצה: לפני ההפעלה, מלאו את params בארגומנטים המתועדים. לאחר קבלת התשובה, המתאם צריך לקרוא רק שדות שאומתו מול JSON בפועל של הנתיב שנבחר.
def fetch_media_chunk(username: str, params: dict) -> dict:
query = {
**params,
"username": username,
"license_key": KEY,
}
response = requests.get(
f"{BASE}\/v1\/user\/medias\/chunk",
params=query,
timeout=30,
)
response.raise_for_status()
return response.json()
בשלב הבא כתבו פונקציית מתאם שתמיר את התשובה לפורמט פנימי. לצורך הניתוח עשויים להידרש מזהה יציב של הפרסום, היוצר, הקישור, תאריך הפרסום, סוג המדיה והמונים ציבוריים זמינים. בדקו את השמות והסוגים המדויקים של השדות בתיעוד ובדוגמת JSON. אם מדד חסר, שמרו אותו כערך ריק במקום להציב אפס: אפס מציין מונה שנמדד כ-0, ואילו ערך ריק מציין שאין נתונים.
def normalize_media(item: dict, username: str, observed_at: str) -> dict:
# ציינו מפתחות רק לאחר בדיקת ה-JSON של נקודת הקצה שנבחרה.
return {
"username": username,
"media_id": item.get("DOCUMENTED_MEDIA_ID_KEY"),
"media_url": item.get("DOCUMENTED_MEDIA_URL_KEY"),
"published_at": item.get("DOCUMENTED_PUBLISHED_AT_KEY"),
"media_type": item.get("DOCUMENTED_MEDIA_TYPE_KEY"),
"likes": item.get("DOCUMENTED_LIKE_COUNT_KEY"),
"comments": item.get("DOCUMENTED_COMMENT_COUNT_KEY"),
"observed_at": observed_at,
}
החליפו את שמות המפתח הזמניים במפתחות המדויקים מהתשובה של נקודת הקצה המסוימת, והוסיפו בדיקה למיפוי על סמך דוגמת JSON שמורה. כך, שינוי בסכמה יזוהה בעת עדכון האינטגרציה, והדוגמה לא תציג שמות שדות משוערים כאילו הם חוזה מאומת.
שמרו תצפיות, לא רק ערכים נוכחיים
CSV עשוי להתאים לאב-טיפוס; לעבודה שוטפת מתאימים PostgreSQL, Supabase או מאגר נתונים אנליטי. טבלת תצפיות יכולה להכיל את השדות username, media_id, published_at, observed_at, likes, comments ו-JSON גולמי. הצמד media_id ו-observed_at מגדיר תמונת מצב ייחודית. טבלת פרופילים נפרדת תשמור את רשימת החשבונות שבמעקב ואת תאריך הוספתם לניטור.
שמירת התשובה הגולמית מועילה לניפוי שגיאות ולבנייה מחדש של הנתונים המנורמלים. הגבילו את תקופת השמירה בהתאם למטרת הפרויקט ולכללי הארגון, פקחו על הגישה לטבלאות ואל תאספו מידע שאינו נחוץ לניתוח שבחרתם. עבור CRM ופעולות שיווק ישירות, יש לקבוע בנפרד את הבסיס המשפטי החל: העובדה שנתונים ציבוריים זמינים מבחינה טכנית אינה מכריעה את הסוגיה הזאת.
CREATE TABLE media_observations (
username TEXT NOT NULL,
media_id TEXT NOT NULL,
media_url TEXT,
published_at TIMESTAMPTZ,
observed_at TIMESTAMPTZ NOT NULL,
media_type TEXT,
likes BIGINT,
comments BIGINT,
raw_json JSONB,
PRIMARY KEY (media_id, observed_at)
);
הוסיפו רשומות באצווה לאחר בדיקה מוצלחת של התשובה. בהרצה חוזרת של אותה משימה, צירוף המפתח הראשי ימנע יצירה מקרית של תמונת מצב כפולה; באפליקציה אפשר להשתמש בהוספה שמדלגת על התנגשויות. הרצה חדשה במועד אחר תשמור שורה נפרדת ותמשיך את סדרת הנתונים לאורך זמן.
חשבו מדדים שעונים על השאלה
מדד בסיסי לקצב הפרסום הוא מספר פריטי המדיה הייחודיים של החשבון בפרק זמן נתון. קל לחשב אותו לפי published_at, אם השדה קיים ופוענח כראוי. כדי להעריך שינוי בתגובות הציבוריות, השוו בין שתי תצפיות של אותו media_id: השינוי המוחלט בלייקים הוא המונה המאוחר פחות המונה המוקדם, והשינוי היחסי הוא השינוי חלקי הערך המוקדם. אותו חישוב חל על תגובות.
אם הערך המוקדם הוא אפס או חסר, אי אפשר לחשב גידול יחסי; הציגו את ההפרש המוחלט וציינו במפורש שאין בסיס לחישוב אחוזים. המונים עשויים להשתנות בין תצפיות, ולכן הדוח צריך לציין את המרווח בין תמונות המצב ואת מועד האיסוף האחרון. הפרטים האלה מסייעים לקוראים לפרש את הנתונים כראוי.
def growth(previous, current):
if previous is None or current is None:
return {"delta": None, "rate": None}
delta = current - previous
rate = None if previous == 0 else delta \/ previous
return {"delta": delta, "rate": rate}
אל תצמצמו חשבונות לציון יחיד בלי משקולות שניתן להסביר. דוח שימושי בדרך כלל מציג זה לצד זה את מספר הפרסומים, חציון הלייקים והתגובות לפרסום, התפלגות הפורמטים ואת השינוי בתגובות לאורך פרק זמן זהה של גיל הפרסום. החציון מצמצם את ההשפעה של פוסט חריג אחד; מספר הפרסומים מציין את גודל המדגם שעליו מבוססת ההשוואה.
אפשר להתחשב בגיל הפרסום בשתי דרכים. הראשונה היא לאסוף מונים באופן קבוע, למשל במרווחים שווים לאחר גילוי המדיה בפעם הראשונה. השנייה היא להשוות פרסומים שנכנסו לאותו טווח זמן, באמצעות תצפיות שגילן דומה. אם הרצה מתוזמנת מתפספסת, אל תציגו את הדינמיקה בפועל כגידול מדויק של 24 שעות: חשבו את המרווח לפי חותמות הזמן.
הפכו את ההרצה לאוטומטית ובקרו את איכות הנתונים
תזמנו את האיסוף באמצעות cron, GitHub Actions או מתזמר ETL. סדר המשימות פשוט: לקרוא את רשימת החשבונות, לבקש את המנות הדרושות, לבדוק את סטטוס ה-HTTP ואת מבנה התשובה, לנרמל את הנתונים, לשמור תמונת מצב ולתעד את ההרצה. בכל הפעלה תעדו את מספר החשבונות שעובדו, פריטי המדיה, השגיאות ומשך הזמן — כך תוכלו להבחין בין שינוי אמיתי בפעילות לבין כשל באיסוף.
במקרה של שגיאות זמניות, השתמשו במספר מוגבל של ניסיונות חוזרים עם השהיה, ובתגובה שגויה שמרו את הקשר הבקשה בלי מפתח סודי. אל תפעילו לולאה אינסופית על סמני המשך: העצירה צריכה להתבצע בהתאם לתנאי הסיום שמצוינים בתשובת נקודת הקצה. אם התיעוד מגדיר מגבלות או כללי שימוש, התאימו את תדירות האיסוף ואת גודל המדגם בהתאם.
הפרמטר cache_timeout מצוין בדף IG API עבור נתיבים נתמכים. מטמון מועיל כאשר בקשה חוזרת בחלון זמן קצר אינה מוסיפה ערך; בחרו מרווח איסוף שמתאים לשאלה האנליטית. לדוגמה, תמונת מצב יומית מתאימה יותר לסקירה שבועית מאשר בקשות חוזרות ותכופות לאותם פרופילים ללא מטרה מוגדרת.
לפני הפעלת לוח זמנים קבוע, בדקו מדגם קטן. שמרו דוגמת תשובה, בדקו את המזהים והתאריכים, השוו בין השדות המנורמלים ל-JSON המקורי ובדקו ידנית כמה שורות. הוסיפו בדיקות לערכים חסרים, רשימות ריקות ופורמט בלתי צפוי. אם ה-API משתנה, בדיקות כאלה יזהו את הבעיה מהר יותר מדוח לא עקבי בסוף השבוע.
מה התפקיד של AI כאן
AI מתאים לשלב האחרון — ניסוח תיאור תמציתי של תוצאות שכבר חושבו. העבירו למודל נתונים מצרפיים וקישורים לפרסומים, ולא ארכיון גולמי שלם: למשל, מספר פריטי המדיה לפי שבוע, חציון התגובות הציבוריות ורשימת הפרסומים עם השינוי הגדול ביותר בפרק זמן מוגדר. בקשו מהמודל לנסח ממצאים ולצרף את מזהי הרשומות שעליהן הם מבוססים.
עדיף להשאיר את חישוב המדדים לקוד רגיל, כדי שאותו כלל יפיק תוצאה ניתנת לשחזור. מודל יכול להכין תקציר טקסטואלי, לקבץ כיתובים לפי נושאים שהוגדרו מראש או להציע שאלות לבדיקה ידנית. בסיווג לפי נושאים, שמרו את תווית המודל בנפרד מהכיתוב המקורי וציינו את גרסת ההנחיה או המסווג, כדי ששינויים עתידיים לא ישכתבו את ההיסטוריה בלי שתשימו לב.
אל תהפכו דוח אוטומטי להחלטה אוטומטית על העסקה, חוזה או הערכה של אדם מסוים. השתמשו בנתונים ציבוריים לניתוח תוכן מוגבל ובדקו את המסקנות ידנית, במיוחד כשהן משפיעות על החלטות עסקיות. כך נשמרת התועלת של הניטור, ובמקביל מופרדים המונים מדידים מפרשנות.
כך נראית התוצאה
לאחר כמה מחזורי איסוף תתקבל טבלה שמראה מתי התגלה כל פרסום, כמה תגובות היו בכל תצפית וכיצד המדדים השתנו. סיכום שבועי יוכל לענות על שאלות מעשיות: מי פרסם באופן קבוע, באילו פורמטים נעשה שימוש בתדירות גבוהה יותר, אילו פרסומים צברו תגובות בין תמונות מצב בנות-השוואה, והיכן עדיין חסרים נתונים להשוואה בטוחה.
תהליך כזה מסייע להחליף בדיקות ידניות מזדמנות במחקר שניתן לחזור עליו. הוא אינו מחליף ניתוח איכותני של התוכן: המדדים מתארים את תדירות הפרסום ואת התגובות הציבוריות הזמינות, ואילו המשמעות, הקהל וההתאמה למותג דורשים הערכה נפרדת. עם זאת, לוח זמנים אחיד, היסטוריה שמורה והיגיון חישובי מפורש הופכים את ההערכות האלה לניתנות לבדיקה ומתאימות לעבודה צוותית.
כדי להתחיל, פתחו את דף IG Scraper API, בדקו את הפרמטרים של נתיב הפרסומים ב-תיעוד Postman, ואז ממשו מתאם על חשבון בדיקה ושמרו את תמונת המצב הראשונה. לאחר אימות הסכמה, הוסיפו תזמון, בקרת שגיאות ודוח המבוסס על המדדים שנבחרו.