למה Scrapers בסיסיים נכשלים מול City Market
הטעות הראשונה שאני רואה שוב ושוב היא להתייחס ל-City Market כאל אתר מסורתי. אתה שולח בקשת GET, מקבל HTML, ומצפה למצוא את כל המוצרים והמחירים בתוך ה-DOM. זה פשוט לא עובד ככה. האתר טוען מעטפת אפליקציה ראשונית, ורק אז קורא ל-API פנימי כדי לאכלס את רשימות המוצרים. ה-scraper שלך, שמריץ בקשה פשוטה, רואה רק את השלד, בלי הנתונים.
ה-failure scenario הקלאסי הוא scraper שמצליח לעבור דף או שניים ואז מתחיל לקבל שגיאות 403 או דפים ריקים. למה? כי הוא לא מנהל סשן כמו שצריך. City Market, כמו רוב אתרי האיקומרס, משתמש בסט של קוקיז ו-headers (כמו x-csrf-token) כדי לוודא שהבקשות מגיעות מדפדפן אמיתי. בלי לשמור ולשלוח את הקוקיז הנכונים בכל בקשה עוקבת, המערכת מזהה אותך כאוטומציה תוך דקות. ראיתי מערכות שנבנו כך וקרסו עם שיעורי הצלחה של מתחת ל-40% אחרי 100 בקשות בלבד, מה שהופך אותן לחסרות תועלת עבור איסוף קטלוג City Market מלא. זה לא רק עניין של User-Agent. זה עניין של התנהגות רשת שמחקה משתמש אמיתי.
ה-Stack הנכון לאיסוף קטלוג מלא
אז איך כן ניגשים לזה? תפסיקו עם Selenium לפרויקטים חדשים. Playwright מנצח אותו ב-2025 בכל מטריקה רלוונטית, במיוחד בביצועים ויציבות. כשמדובר באתר SPA כמו City Market, השימוש בדפדפן אמיתי (headless) הוא נקודת הפתיחה ההגיונית. הוא מריץ את כל ה-JavaScript, מבצע את קריאות ה-API ברקע ומציג לך את ה-HTML הסופי, המרונדר במלואו.
היתרון הוא שאתה לא צריך לעשות reverse engineering ל-API שלהם (לפחות לא בהתחלה). אתה פשוט מנווט לקטגוריה, גולל למטה כדי לטעון את כל המוצרים (pagination דינמי), ומחלץ את הנתונים. בקטלוג שמכיל, לפי הערכות, בין 30,000 ל-50,000 מוצרים, זו משימה שדורשת אוטומציה יציבה. Playwright נותן לך את היכולת לחכות לאלמנטים ספציפיים או לבקשות רשת מסוימות לפני שאתה ממשיך, מה שמוריד דרמטית את כמות ה-flaky tests והריצות הכושלות. כדי להיראות אפילו יותר אנושי, כדאי להשתמש בתוספים ייעודיים. תוכלו לקרוא על זה יותר ב-מדריך Playwright stealth שלנו, שמסביר איך להסתיר את העובדה שאתם מריצים דפדפן אוטומטי.
ניטור מחירים ומלאי: איפה המשחק האמיתי נמצא
איסוף קטלוג ראשוני זה נחמד, אבל הערך האמיתי נמצא בנתונים דינמיים. ניטור מחירים City Market ומעקב אחר זמינות דורשים גישה מתוחכמת יותר. המחיר והמלאי של מוצר יכולים להשתנות בין סניפים שונים. אם תשלח בקשה גנרית, סביר להניח שתקבל מחירים מהסניף הראשי או ממרכז לוגיסטי כלשהו. כדי לקבל נתונים מדויקים, אתה צריך לדמות משתמש שבחר סניף ספציפי.
בפועל, זה אומר שה-scraper שלך צריך לנהל קוקיז או לשלוח פרמטר ב-API call שמציין את מזהה הסניף. כאן, היכולת של Playwright ליירט בקשות רשת (network interception) היא קריטית. אתה יכול לראות בדיוק לאיזה endpoint האתר פונה כדי לקבל זמינות ונתוני מבצעים, ולראות איזה payload הוא שולח. עם המידע הזה, אפשר לבנות scraper ממוקד הרבה יותר. לדוגמה, במקום לטעון דף שלם, אפשר לחזור על קריאת ה-API הספציפית הזו עם מזהי סניפים שונים. זה חוסך המון זמן ומשאבים. כדי להתמודד עם הגבלות מבוססות מיקום גיאוגרפי, חובה להשתמש בפרוקסי איכותיים. קראו על זה במדריך שלנו על איך לבחור פרוקסי residential כדי להבין את ההבדלים והחשיבות שלהם בפרויקטים כאלה.
מתי Headless Browser הוא Overkill
אמרתי ש-Playwright הוא נקודת פתיחה מצוינת, וזה נכון. אבל הוא לא תמיד הפתרון היעיל ביותר. הרצת מאות מופעים של דפדפן במקביל היא יקרה מבחינת CPU ו-RAM. אם המטרה שלך היא לאסוף נתונים בקנה מידה עצום ובקצב גבוה, למשל עבור API / קובץ נתונים City Market שמתעדכן כל שעה, הגישה הנכונה היא לעשות reverse engineering ל-API הפנימי שלהם.
זה דורש יותר עבודת חקירה ראשונית. צריך לפתוח את ה-DevTools, לעקוב אחר בקשות ה-XHR/Fetch, להבין את מנגנון האימות (authentication), ולפענח את מבנה הבקשות והתשובות. אבל ברגע שיש לך את זה, אתה יכול לוותר על הדפדפן לחלוטין ולעבור לבקשות HTTP טהורות (עם ספריה כמו httpx ב-Python). המהירות קופצת בסדרי גודל. במקום לעבד דף שלם של 2MB, אתה שולח בקשה של 2KB ומקבל תגובת JSON של 50KB. קצב הבקשות יכול לעלות מעשרות בודדות לדקה לאלפים. החיסרון? זה שביר. כל שינוי קטן ב-API מצד City Market, וה-scraper שלך נשבר. זו הסיבה שגישה כזו דורשת ניטור ובדיקות רציפות. גם כאן, סביר שתתקל ב-rate limiting, ולכן חשוב לדעת איך לטפל בזה נכון, כפי שפירטנו במאמר על טיפול בשגיאות 429.
בניית Data Pipeline למודיעין מתחרים
איסוף הנתונים הוא רק החלק הראשון. כדי להפוך את המידע הגולמי הזה לכלי עבודה עבור מודיעין מתחרים City Market, צריך לבנות data pipeline אמין. זה מתחיל במבנה הנתונים. הקפד על סכמה קבועה וברורה לכל מוצר: שם, מק"ט, מחיר, מבצע, קטגוריה, תת-קטגוריה, זמינות בסניפים וכו'. שמור את הנתונים בפורמט שקל לעבוד איתו, בין אם זה מסד נתונים כמו PostgreSQL או קבצי Parquet ב-S3.
השלב הבא הוא ניקוי ו-normalization. שמות מוצרים יכולים להשתנות מעט, קטגוריות יכולות להיות לא עקביות. צריך לכתוב לוגיקה שמנרמלת את הנתונים כדי לאפשר השוואות מדויקות. לדוגמה, 'קוקה קולה 1.5 ליטר' ו-'קוקה-קולה בקבוק 1.5ל' צריכים להיות ממופים לאותו מוצר. לבסוף, יש את שכבת הניטור וההתראות. המערכת צריכה לזהות באופן אוטומטי כשה-scraper נשבר (למשל, ירידה פתאומית של 90% בכמות המוצרים שנסרקו), להתריע על שינויי מבנה באתר, ולספק דשבורד שמציג את בריאות המערכת. בלי המעטפת הזו, ה-scraper הכי טוב בעולם הוא פצצת זמן מתקתקת.
