למה הגישה הקלאסית פשוט לא עובדת כאן

נתחיל מהברור מאליו. אתר כמו adidas.co.il לא מגיש דפי מוצר סטטיים. כשאתה מבקש URL של מוצר, השרת מחזיר שלד HTML אפליקטיבי, ורוב העבודה מתבצעת בדפדפן של המשתמש. קריאות API רבות יוצאות ברקע כדי לאכלס את הדף במידע: תמונות, תיאורים, ביקורות, וחשוב מכל – מחירים וזמינות במלאי. אם ה-scraper שלך רק עושה GET ל-URL, הוא מקבל את השלד הזה וזהו. הוא לא רואה את הנתונים האמיתיים.

זהו ה-failure mode הראשון והנפוץ ביותר. ראיתי צוותים מבזבזים שבועות בניסיון למצוא את המידע ב-HTML, רק כדי להבין שהם מסתכלים במקום הלא נכון. הגישה הזו נכשלה כבר לפני חמש שנים, והיום היא פשוט לא רלוונטית לאתרים בסדר גודל כזה. הניסיון השני, בדרך כלל, הוא לחפש את קריאות ה-API הפנימיות האלה. זו גישה חכמה יותר, אבל גם היא מורכבת. אותן קריאות API מאובטחות לרוב עם טוקנים, headers דינמיים, וטכניקות fingerprinting שנועדו להבטיח שהבקשה מגיעה מדפדפן אמיתי. הנדסה לאחור של הלוגיקה הזו היא משימה שדורשת זמן רב ותחזוקה מתמדת. כל שינוי קטן ב-frontend של אדידס יכול לשבור לך את כל הלוגיקה. לכן, הפתרון היעיל ביותר הוא לא לנסות להערים על המערכת, אלא לעבוד איתה.

Playwright הוא הבחירה הנכונה, אבל זה לא מספיק

הפתרון הוא להשתמש ב-Headless Browser, וכאן Playwright הוא הבחירה המודרנית והיעילה ביותר. הוא מאפשר לנו להריץ דפדפן אמיתי (כמו Chromium) בצורה פרוגרמטית, שיודע להריץ את כל ה-JavaScript, לבצע את קריאות ה-API, ולרנדר את הדף בדיוק כפי שמשתמש היה רואה אותו. רק אחרי שהדף נטען במלואו, כולל כל המידע הדינמי, אנחנו מתחילים את תהליך ה-scraping.

אבל פשוט להריץ Playwright לא יספיק. מערכות הגנה מזהות בקלות headless browsers סטנדרטיים. לכן, חובה להשתמש בתוספים כמו playwright-extra עם puppeteer-extra-plugin-stealth. התוסף הזה מבצע עשרות שינויים קטנים כדי להסוות את האוטומציה: הוא משנה מאפייני navigator, מסיר properties שקיימים רק ב-headless mode, ומחקה התנהגות אנושית. בלי הצעדים האלה, סביר שתקבלו CAPTCHA או חסימת IP מהר מאוד. כשמפתחים מערכת לאיסוף קטלוג Adidas Israel המלא, שמכיל כ-8,000 דפי מוצר, יציבות היא שם המשחק. אנחנו מכוונים לשיעור הצלחה של 99% ומעלה לבקשה. עם Playwright ו-stealth, זה יעד ריאלי. בלי זה, תתכוננו ל-rate limiting ולשגיאות בלתי פוסקות. המדריך המלא שלנו על הנושא נמצא כאן: מדריך Playwright stealth.

איך בונים תהליך יציב לניטור מחירים ומלאי

אחד ה-use cases המרכזיים הוא ניטור מחירים Adidas Israel ומעקב מלאי/זמינות Adidas Israel. המטרה היא לאסוף נתונים מדויקים ובתדירות גבוהה. כאן נכנסת לתמונה ארכיטקטורת ה-scraper. אי אפשר פשוט להריץ לולאה על כל המוצרים מ-IP יחיד. תהליך כזה ייחסם תוך פחות מ-100 בקשות.

הארכיטקטורה הנכונה מורכבת מכמה חלקים. ראשית, תור עבודות (כמו RabbitMQ או Redis) שמכיל את כל ה-URLs שצריך לסרוק. שנית, צי של workers (יכולים להיות קונטיינרים של Docker) שכל אחד מהם מריץ instance של Playwright. שלישית, והכי חשוב, מערך Proxy Rotation. עבור אתר ישראלי כמו אדידס, חובה להשתמש ב-proxies ישראליים. שימוש ב-IP מחו"ל הוא דגל אדום מיידי למערכות הגנה. אני ממליץ בחום על איך לבחור פרוקסי residential איכותיים, שמספקים IPs של משתמשים אמיתיים. כל worker צריך לקבל IP חדש כל כמה בקשות או אחרי פרק זמן קבוע. קצב הבקשות צריך להיות מוגבל פר IP, למשל לא יותר מ-15 בקשות בדקה. זה אולי נשמע איטי, אבל עם 20 workers במקביל, אפשר לכסות את כל הקטלוג תוך מספר שעות. הנתונים שנאספים, כמו שמות מוצרים ומפרטים, נשמרים במסד נתונים ומוכנים לניתוח.

תרחיש הכשל הנפוץ: התמודדות עם מבנה נתונים משתנה

אז בניתם מערכת שעובדת. היא משתמשת ב-Playwright, יש לה proxies, והיא אוספת נתונים. ואז, בוקר אחד, 70% מהריצות נכשלות. אתם בודקים, והאתר נראה תקין. מה קרה? סביר להניח שצוות ה-frontend של Adidas Israel שינה selector. אולי div עם class product-price הפך ל-span עם data-attribute data-test-id="price-final". זהו תרחיש הכשל השקט והמסוכן ביותר, כי ה-scraper לא מקבל שגיאה (הדף נטען), הוא פשוט מחזיר null עבור שדה המחיר.

כדי להתמודד עם זה, חייבים לבנות מערכת ניטור ובקרת איכות על הדאטה עצמו. אל תסמכו רק על לוגים של הצלחה או כישלון ברמת הרשת. אחרי כל ריצה, תריצו בדיקות אוטומטיות על הדאטה שנאסף. לדוגמה: האם לפחות 95% מהמוצרים חזרו עם מחיר? האם אחוז המוצרים ללא שם נמוך מ-1%? האם מבנה הקטגוריות נראה הגיוני? אם אחת מהבדיקות נכשלת, המערכת צריכה להרים דגל ולשלוח התראה מיידית. זה ההבדל בין scraper חובבני למערכת דאטה מקצועית. בנוסף, חשוב לתכנן את ה-selectors בצורה חכמה. העדיפו selectors יציבים יותר כמו data-attributes שנועדו לבדיקות E2E על פני שמות class שמשתנים לעתים קרובות. לפעמים, הדרך הטובה ביותר היא לחלץ את כל אובייקט ה-JSON שמוטמע בתג <script type="application/ld+json">, שמכיל מידע מובנה על המוצר ונוטה להיות יציב יותר.

מאיסוף קטלוג ועד ליצירת API / קובץ נתונים

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

השלב האחרון בתהליך הוא יצירת API / קובץ נתונים מסודר. אחרי שהמידע נאסף, עבר ניקוי וולידציה, הוא נשמר במסד נתונים (למשל PostgreSQL). משם, אפשר לחשוף אותו בכמה דרכים. האפשרות הפשוטה היא יצוא יומי או שבועי לקובץ CSV או JSON שמועלה ל-storage כמו S3. זה פתרון מצוין לניתוח אד-הוק או להזנה למערכות BI. האפשרות המתקדמת יותר היא לבנות API RESTful פנימי שמאפשר לשאילתות בזמן אמת. לדוגמה, נקודת קצה /products?sku=H04240 שתחזיר את כל היסטוריית המחיר והמלאי עבור מוצר ספציפי. בניית API כזה הופכת את ה-scraper מכלי חד-פעמי לנכס דאטה אסטרטגי שכל הארגון יכול להשתמש בו. אם אתם נתקלים בחסימות תכופות, כמו שגיאות 429, כדאי לקרוא את המדריך שלנו על טיפול בשגיאות 429, שמציע אסטרטגיות התמודדות יעילות.