למה ה-Scraper הראשון שלכם נכשל תוך 5 דקות
הטעות הקלאסית היא להתייחס לאתר כמו רמי לוי כמסמך HTML סטטי. אתה שולח בקשת GET, מקבל HTML, ומנסה לנתח אותו. הבעיה היא שה-HTML שאתה מקבל הוא כמעט ריק. הוא שלד. כל התוכן — מוצרים, מחירים, מבצעים — נטען דינמית אחרי שהדף הראשוני עולה, באמצעות קריאות JavaScript ל-API הפנימי של האתר. זו הסיבה שכלים כמו requests פשוט לא רואים את המידע.
כאן נכנס לתמונה הצורך ב-Headless Browser. תשכחו מ-Selenium; הוא איטי ומיושן. ב-2025, Playwright הוא הבחירה הנכונה. הוא מהיר יותר, האוטומציות שלו אמינות יותר, והוא נותן לך שליטה גרעינית על הרשת. המטרה הראשונית שלכם באיסוף קטלוג רמי לוי היא לא לגרד את ה-HTML, אלא להשתמש ב-Playwright כדי ליירט את קריאות ה-API שהדפדפן מבצע ברקע. אתם מריצים את הדפדפן, מנווטים לעמוד קטגוריה, ופשוט מאזינים לתעבורת ה-XHR/Fetch ב-Developer Tools. שם נמצא הזהב האמיתי. ברגע שיש לכם את ה-endpoints, אתם יכולים להתחיל לחשוב על השלב הבא: איך לדמות את הקריאות האלה ישירות, בלי העול של רינדור דף שלם בכל פעם.
הנדוס לאחור של ה-API: המטרה האמיתית שלכם
אחרי שזיהינו שהדאטה מגיע מ-API פנימי, המשימה משתנה. אנחנו כבר לא 'מגרדים' דפים, אנחנו מתקשרים עם API. פתחו את כלי המפתחים בדפדפן, נווטו לאתר רמי לוי, בחרו סניף, וחפשו בקשות לרשת שנראות כמו /api/v1/products או /api/branches/{branchId}/catalog. בדרך כלל תמצאו endpoint שמקבל מזהה קטגוריה או מילת חיפוש, ומחזיר JSON עם רשימת מוצרים.
ה-JSON הזה הוא המטרה. הוא מכיל את כל מה שצריך בצורה מובנית: שמות מוצרים, מק"טים, תמונות, וכמובן, מחירים ומבצעים. העבודה עם JSON טהור מהירה פי 100 מניתוח HTML. אין צורך ב-CSS selectors מסורבלים שנשברים כל פעם שהעיצוב משתנה. אתם פשוט עובדים עם אובייקטים. האתגר הוא להבין את ה-Headers הנדרשים. סביר להניח שתצטרכו לשלוח טוקן אימות (Authorization Bearer Token), מזהה סשן בקוקי, ואולי גם headers מותאמים אישית כמו X-Client-Version. כל אלה ניתנים לזיהוי על ידי ניתוח הבקשות שהדפדפן שלכם שולח. המטרה היא ליצור לקוח API משלכם, שיכול לבקש נתונים ישירות מהשרת של רמי לוי, מה שמאפשר איסוף קטלוג רמי לוי בקנה מידה גדול.
אתגר הסניפים והמלאי: איך לאסוף דאטה מדויק
ברשתות סופרמרקטים, המחיר והזמינות של מוצר אינם ערכים גלובליים. הם תלויי סניף. זה מוסיף שכבת מורכבות משמעותית. כשאתם מבצעים מעקב מלאי/זמינות רמי לוי, אתם חייבים לנהל סשן (Session) עבור כל סניף בנפרד. בדרך כלל, בחירת סניף באתר שותלת קוקי בדפדפן (למשל, store_id=123) או דורשת שליחת מזהה סניף בכל קריאת API.
הקטלוג של רמי לוי מכיל מעל 15,000 מוצרים. אם יש 50 סניפים, אנחנו מדברים על 750,000 נקודות דאטה פוטנציאליות למחיר/מלאי. ניסיון לסרוק את כל זה באופן סדרתי ייקח ימים. כאן נכנסת לתמונה עבודה מקבילית. אם אתם לא משתמשים ב-asyncio או ארכיטקטורה מבוססת תורים (כמו Celery עם RabbitMQ), אתם מבזבזים 90% מהזמן בהמתנה לתגובות רשת. עם תשתית נכונה וניהול פרוקסי חכם, אפשר להגיע לקצב של 20-30 בקשות בשנייה בלי לעורר חשד. צריך לזכור שכל IP יצטרך לנהל את הקוקיז שלו בנפרד כדי לא לערבב בין נתוני הסניפים. זהו אחד האתגרים המרכזיים שהופכים פרויקט כזה ממשימה פשוטה למערכת מורכבת שדורשת הבנה עמוקה של ניהול פרוקסי למניעת חסימות.
מתי הכל מתפרק: מלאי רפאים וסשנים שמתאפסים
גם עם ה-API המהונדס והתשתית המקבילית, יש נקודות כשל קלאסיות באתרים מסוג זה. התרחיש הכי מתסכל שנתקלתי בו הוא 'מלאי רפאים'. ה-API מדווח שמוצר מסוים נמצא במלאי, אבל כשמנסים להוסיף אותו לעגלה (דרך אוטומציה או ידנית), מקבלים שגיאה. זה קורה כי מערכת המלאי הראשית ומערכת ה-cache שפונה לאתר אינן מסונכרנות במאה אחוז. הפתרון היחיד הוא להוסיף שלב אימות: עבור מוצרים קריטיים, ה-scraper צריך לדמות 'הוספה לסל' כדי לוודא שהמלאי אמיתי. זה מאט את התהליך, אבל מגדיל את אמינות הנתונים מ-95% ל-99.9%.
בעיה נוספת היא 'איפוס סשן'. אחרי מאות או אלפי בקשות, גם עם קוקיז תקינים, השרת יכול להחליט שהסשן שלכם 'ישן' ומאפס אתכם לסניף ברירת המחדל, בלי החזרת קוד שגיאה ברור. פתאום, באמצע סריקת סניף באילת, אתם מתחילים לקבל נתונים מסניף בחיפה. הדרך היחידה להתמודד עם זה היא לבצע בדיקות שפיות תקופתיות. כל 100 בקשות, למשל, בצעו קריאה ל-endpoint כמו /api/users/me או /api/session/details וודאו שמזהה הסניף הנוכחי תואם למה שאתם מצפים. זהו סוג הדיבאגינג שמפריד בין פרויקט חובבני למערכת דאטה מקצועית, וכדאי לקרוא על טכניקות מתקדמות לדיבאגינג של scrapers כדי להיות מוכנים.
הפיכת הנתונים למודיעין תחרותי שמיש
איסוף הנתונים הוא רק חצי מהעבודה. דאטה גולמי בקבצי JSON הוא חסר תועלת עד שלא הופכים אותו לתובנות. השלב הבא הוא לבנות תהליך ETL (Extract, Transform, Load) שמנרמל את המידע ומכניס אותו לדאטהבייס מובנה. כאן מתחיל הערך האמיתי של מודיעין מתחרים רמי לוי. אתם יכולים לעקוב אחרי שינויי מחיר לאורך זמן, לזהות מבצעים חדשים ברגע שהם עולים לאוויר, ולהשוות את קטלוג המוצרים והמחירים מול מתחרים.
התוצר הסופי יכול להיות API פנימי משלכם או קובץ נתונים יומי. לדוגמה, אפשר לייצר API / קובץ נתונים רמי לוי שמספק כל בוקר קובץ CSV עם כל המוצרים, המחירים והמלאי בכל סניף. זה מאפשר לצוותי אנליסטים ומודיעין עסקי לקבל החלטות מבוססות נתונים עדכניים. בניית מערכת כזו דורשת חשיבה על ניטור, התראות על שגיאות, וטיפול בשינויים במבנה האתר. האתר ישתנה. ה-API ישתנה. מערכת טובה לא רק אוספת נתונים, אלא גם מזהה מתי היא נשברת ומתריעה על כך באופן אוטומטי, מה שמבטיח שהנתונים שלכם יישארו אמינים ורלוונטיים.
