למה Requests לא יספיק לכם כאן (ומה כן עובד)
בואו נניח את זה על השולחן: אם אתם מנסים לעשות requests.get על URL של מוצר בקרביץ, אתם מבזבזים את הזמן. ה-HTML הראשוני שהשרת מחזיר כמעט ריק מתוכן משמעותי. המידע על המוצר – שם, מפרט, זמינות, ובעיקר המחיר – נטען דינמית דרך סדרת קריאות API אסינכרוניות שהדפדפן מריץ. הניסיון להנדס לאחור את הקריאות האלה הוא מסלול שמוביל לתחזוקה שוטפת כואבת. כל שינוי קטן ב-endpoint, ב-headers, או ב-payload ישבור לכם את ה-scraper.
הפתרון היחיד שעובד באופן עקבי ב-2025 לאתרים כאלה הוא שימוש ב-headless browser. ותשכחו מ-Selenium; הוא איטי, מסורבל והטביעת אצבע שלו זוהתה כבר לפני שנים. הבחירה הנכונה היא Playwright. הוא מהיר יותר, ה-API שלו נקי, והוא מגיע עם יכולות מובנות שהופכות את החיים לקלים יותר. בנוסף, קרביץ יושב מאחורי Cloudflare. זה אומר שאתם לא רק צריכים לרנדר JavaScript, אתם צריכים לעבור אתגרים אקטיביים של בוטים. ניסיון לעשות את זה ידנית הוא כמעט בלתי אפשרי בקנה מידה גדול. שימוש ב-Playwright עם תוספי stealth הוא קו ההגנה הראשון וההכרחי. קראו את המדריך המלא לעקיפת Cloudflare כדי להבין את עומק האתגר. בלי זה, רוב הבקשות שלכם אפילו לא יגיעו לשרת האפליקציה של קרביץ.
ארכיטקטורת היעד: מיפוי קטלוג ואיסוף מוצרים
לפני שאתם יורים בקשה אחת לדף מוצר, אתם צריכים מפת דרכים. המטרה הראשונה היא לבצע איסוף קטלוג קרביץ מלא – כלומר, רשימה של כל כתובות ה-URL של המוצרים באתר. קטלוג האתר מונה כ-25,000 מוצרים, הפרוסים על פני מאות קטגוריות ותתי-קטגוריות. הגישה הנכונה היא דו-שלבית:
- זחילת קטגוריות (Category Crawl): התחילו מעמוד הבית וחלצו את כל הקישורים לקטגוריות הראשיות. משם, היכנסו לכל קטגוריה וחלצו את תתי-הקטגוריות. בנו עץ היררכי של כל דפי הקטגוריה באתר. זהו תהליך שצריך לרוץ פעם ביום כדי לזהות קטגוריות חדשות או שינויים במבנה.
- איסוף מזהי מוצר (Product Discovery): עבור כל דף קטגוריה שאספתם, עברו על כל עמודי הפגנציה (pagination) וחלצו רק את ה-URL או את המזהה הייחודי (SKU) של כל מוצר. אל תנסו לחלץ את כל פרטי המוצר בשלב הזה. המטרה היא אך ורק לבנות תור (queue) של משימות חילוץ. זה מפריד בין שלב הגילוי לשלב החילוץ העמוק, ומאפשר לכם לנהל שגיאות בצורה טובה יותר. אם דף קטגוריה נופל, אתם לא מאבדים את נתוני המוצרים שכבר חילצתם.
הפלט של השלב הזה צריך להיות רשימה נקייה של כ-25,000 כתובות URL, מוכנה להזנה לשלב הבא. תהליך זה, אם מבוצע נכון עם 5-10 workers במקביל, אמור לקחת לא יותר מ-30 דקות.
חילוץ ברמת המוצר: מחירים, מבצעים, ומלאי לפי סניפים
כאן מתחיל האתגר האמיתי. לכל אחד מ-25,000 ה-URLs שאספתם, אתם צריכים להריץ מופע של Playwright, לטעון את הדף, להמתין שהרנדור יסתיים ולחלץ את השדות הנדרשים. שני השדות המורכבים ביותר באתר קרביץ הם מחירים ו-מלאי לפי מוצר.
המחיר לא תמיד מופיע כערך יחיד. לעיתים קרובות יש מחיר רגיל, מחיר מבצע, או מחיר לחברי מועדון. חובה למפות את כל הסלקטורים האפשריים ולוודא שהלוגיקה שלכם יודעת להתמודד עם כל המצבים. אל תניחו שסלקטור שעבד היום יעבוד מחר; בנו מערכת התראות שתזהיר אתכם אם אחוז המוצרים ללא מחיר עולה מעל 1%.
האתגר הגדול יותר הוא מעקב מלאי/זמינות קרביץ. הזמינות אינה ערך בוליאני פשוט של 'במלאי/אזל'. היא משתנה פר סניף. המידע הזה נטען בדרך כלל על ידי קריאת API נפרדת לאחר שהמשתמש מקיש על כפתור 'בדיקת זמינות בסניפים'. תצטרכו לאמולץ את האינטראקציה הזו: ללחוץ על הכפתור עם Playwright, להמתין לתגובת ה-API (באמצעות page.wait_for_response), ולנתח את ה-JSON שחוזר. זהו תהליך איטי, שמוסיף 2-3 שניות לכל דף. לכן, חשוב להחליט אם אתם באמת צריכים את המידע הזה עבור כל המוצרים, כל יום. זהו trade-off קלאסי בין שלמות הנתונים וזמן הריצה.
מודיעין מתחרים ו-API נתונים: הפיכת המידע הגולמי לתובנות
איסוף הנתונים הוא רק חצי מהעבודה. הערך האמיתי מגיע מהיכולת להפוך את המידע הגולמי למוצר שמיש. שני מקרי שימוש מרכזיים הם מודיעין מתחרים ו-API / קובץ נתונים.
עבור מודיעין מתחרים, המטרה היא לא רק לאסוף את המחיר היומי. אתם צריכים לבנות היסטוריה. שמירת snapshot יומי של כל מוצר מאפשרת לכם לזהות מגמות: שינויי מחיר, מוצרים חדשים שהופיעו, מוצרים שאזלו מהמלאי ולא חזרו, ושינויים במבצעים. לדוגמה, מעקב אחר קטגוריית 'ראשי דיו' יכול לחשוף אסטרטגיית תמחור אגרסיבית לקראת החזרה לבית הספר. הנתונים האלה, כשהם מוצגים על ציר זמן, הופכים מכאוס של מספרים לסיפור אסטרטגי.
המקרה השני הוא לספק את הנתונים האלה דרך API או כקובץ CSV/JSON יומי. כאן, האמינות והעקביות הן המפתח. הלקוח שלכם לא רוצה לקבל דאטה עם חורים או ערכים שגויים. זה דורש תהליך אימות (validation) קפדני לאחר החילוץ. ודאו שכל מחיר הוא מספר, שכל SKU תואם לתבנית הצפויה, ושאין ערכים ריקים בשדות חיוניים. בנוסף, חשוב לנהל גרסאות של ה-schema שלכם. אם קרביץ מוסיפים שדה חדש, כמו 'זמן אספקה משוער', ה-API שלכם צריך להשתנות בצורה מבוקרת שלא תשבור אינטגרציות קיימות.
איפה כל זה נשבר: כשהפרוקסי שלך בוגד בך
בנינו ארכיטקטורה יפה עם Playwright וניהול תורים. אבל יש נקודת כשל אחת שיכולה להרוס הכל בשקט: ניהול פרוקסי גרוע. כשעושים scraping לאתר בסדר גודל של קרביץ, אתם לא יכולים להשתמש ב-IP הבודד של השרת שלכם. תחסמו תוך פחות מ-100 בקשות. הפתרון הוא רשת של פרוקסים, אבל כאן רוב האנשים טועים.
הם קונים רשימה של פרוקסי datacenter זולים, ונופלים למלכודת הקלאסית: האתר לא חוסם אותם עם שגיאת 403, אלא מגיש להם תוכן שונה. זה יכול להיות דף CAPTCHA, אבל במקרה הגרוע יותר, זה תוכן מזויף או מוגבל. למשל, קרביץ עשוי להציג לכם מחירים ללא מבצעים המיועדים למשתמשים רגילים, או להראות שמלאי אזל בסניפים מסוימים, רק בגלל שה-IP שלכם מסווג כחשוד. אתם מקבלים תגובת 200 OK, ה-scraper שלכם מדווח על הצלחה של 99%, אבל הנתונים שבידכם שגויים ב-30%. זוהי שחיתות נתונים שקטה, הסיוט של כל מהנדס דאטה.
הדרך היחידה להתמודד עם זה היא להשתמש בפרוקסים איכותיים, ובאופן ספציפי, פרוקסי residential. אלה IP של משתמשי בית אמיתיים, והרבה יותר קשה לאתרים לזהות אותם. יתרה מזאת, אתם צריכים לעשות רוטציה חכמה של ה-IPs. אל תשתמשו באותו IP ליותר מ-10-20 בקשות רצופות. חשוב גם לבחור פרוקסי עם מיקוד גיאוגרפי בישראל כדי לקבל את התוכן והמחירים המדויקים. אם אתם רוצים להבין את הניואנסים, יש לנו מדריך מעמיק לבחירת פרוקסי residential.
