למה Medi-Link הוא לא עוד אתר פשוט ל-Scraping
הטעות הראשונה שמהנדסים עושים היא להתייחס ל-Medi-Link כמו אל אתר WordPress סטנדרטי. פתיחת ה-DevTools חושפת את האמת: זו אפליקציית צד-לקוח, כנראה React או Vue, שמדברת עם backend דרך API פנימי. כל המידע החשוב – מחירים, זמינות, מפרטים – לא נמצא ב-HTML הראשוני שמגיע מהשרת. הוא נטען דינמית באמצעות קריאות XHR/Fetch.
זה פוסל על הסף כל גישה שמבוססת על הורדת HTML סטטי. אתם חייבים להריץ JavaScript. וזה אומר שאתם צריכים כלי שיודע לעשות את זה. תפסיקו עם Selenium לפרויקטים חדשים. Playwright מנצח אותו ב-2025 בכל מטריקה רלוונטית: מהירות, יציבות, וה-API שלו פשוט נקי יותר. השליטה ברמת הרשת שהוא נותן לנו היא קריטית כאן. אנחנו יכולים ליירט את קריאות ה-API, לנתח אותן, ואפילו לשכפל אותן ישירות, מה שחוסך לנו את העיבוד הכבד של הדפדפן.
האתר מכיל קטלוג של עשרות אלפי מוצרים, מפוזרים על פני מאות קטגוריות. ניסיון לעבור על כל אלה בסנכרון אחד יארך ימים. אם אתם לא משתמשים ב-async ל-10,000+ דפים, אתם מבזבזים 80% מהזמן על המתנה ל-IO. זו דרישת חובה, לא nice-to-have.
אסטרטגיית ה-Crawl: מאיסוף קטלוג ועד מעקב מלאי
השלב הראשון הוא תמיד איסוף קטלוג Medi-Link המלא. אי אפשר לנטר משהו שלא יודעים שהוא קיים. הגישה הנאיבית היא לעבור על כל הקטגוריות והעמודים, אבל זה איטי ולא יעיל. גישה טובה יותר היא לחפש sitemap.xml. אם הוא קיים ועדכני, זכיתם. אם לא, צריך לעבוד קשה יותר. התחילו מדפי הקטגוריות הראשיים, וכתבו לוגיקה שמטפלת בפג'ינציה – שלרוב תהיה מבוססת על קריאת API שמופעלת בגלילה (infinite scroll) או בלחיצה על כפתור "טען עוד".
אחרי שיש לכם רשימה של כל כתובות ה-URL של המוצרים, מתחילה העבודה האמיתית: מעקב מלאי/זמינות Medi-Link. זהו אחד התרחישים המורכבים ביותר, כי המידע הזה משתנה בתדירות גבוהה. כאן אנחנו צריכים להיות כירורגיים. במקום לרנדר את כל הדף כל פעם, אנחנו מנסים לזהות את אותה קריאת API ספציפית שמביאה את נתוני המלאי. בדרך כלל זו תהיה בקשת GET או POST לנקודת קצה כמו /api/v2/products/{product_id}/stock. זיהוי הבקשה הזו מאפשר לנו לבצע שאילתות ממוקדות ומהירות בהרבה, מבלי להריץ דפדפן מלא לכל מוצר. זה ההבדל בין סקריפט שרץ 4 שעות לסקריפט שמסיים את העבודה ב-15 דקות.
ניהול זהויות ו-Proxy Rotation: איך לא להיחסם אחרי 100 בקשות
בואו נדבר על הנושא הכואב: חסימות. Medi-Link, כמו כל אתר מסחרי רציני, משתמש במנגנוני הגנה. הם לא רוצים שתעשו scraping. אחרי 50-100 בקשות מהירות מאותה כתובת IP, אתם תתחילו לראות שגיאות 429 (Too Many Requests) או CAPTCHA. הפתרון הוא כמובן רשת של פרוקסי.
אבל לא כל פרוקסי יעבוד. פרוקסים של דאטה סנטר הם זולים ומהירים, אבל קל מאוד לזהות ולחסום אותם. לרמה הזו של scraping, אתם צריכים פרוקסי residential. אלה כתובות IP של משתמשים אמיתיים, והרבה יותר קשה למערכות הגנה לסמן אותן כחשודות. המפתח הוא לא רק להשתמש בפרוקסי, אלא לעשות להם רוטציה חכמה. אל תחליפו IP בכל בקשה – זה נראה חשוד. החליפו IP כל כמה דקות, או אחרי מספר מסוים של בקשות. זה מדמה התנהגות אנושית יותר. למדריך מעמיק יותר על הנושא, קראו על איך לבחור פרוקסי residential ואיך ליישם את הלוגיקה.
בנוסף ל-IP, חשוב לנהל טביעות אצבע של הדפדפן. זה כולל user-agent, cookies, ופרמטרים נוספים שדפדפנים שולחים. שימוש ב-Playwright עם תוספים כמו ה-מדריך Playwright stealth יכול לעזור להסוות את העובדה שהדפדפן שלכם מופעל אוטומטית, ולהוריד את הסיכוי לחסימה ב-70-80%.
תרחיש כישלון קלאסי: כשה-API הפנימי משתנה בלי התראה
הנה סיפור אמיתי. בנינו scraper מתוחכם עבור לקוח שרצה מודיעין מתחרים מ-Medi-Link. ה-scraper התבסס על יירוט קריאות ה-API הפנימיות, עקף את הצורך ברינדור דפים, והיה מהיר ויציב. הצלחה של 99.5% בריצה יומית. במשך חודשיים, הכל עבד חלק. ואז, בוקר אחד, המערכת התחילה להחזיר שגיאות על כל הבקשות. 100% כישלון.
מה קרה? צוות הפיתוח של Medi-Link שינה את גרסת ה-API שלהם. נקודת הקצה /api/v1/products הפכה ל-/api/v2/products. מבנה ה-JSON שהוחזר היה שונה, ושם של פרמטר חובה השתנה. ה-scraper שלנו, שהיה בנוי על הנחות קשיחות לגבי מבנה ה-API, נשבר לחלוטין. לא הייתה שום הודעה מוקדמת, כמובן. זה לא API ציבורי.
הלקח כאן הוא קריטי: כשאתם תלויים ב-API פנימי, אתם חייבים לבנות מערכת ניטור ובדיקות חזקה. צריך להיות לכם end-to-end test שרץ כל כמה שעות ומוודא שהסכימה של הנתונים לא השתנתה. בנוסף, חשוב שתהיה לכם אסטרטגיית fallback – אם גישת ה-API נכשלת, ה-scraper צריך לדעת לחזור אוטומטית לגישת רינדור הדפדפן המלאה (האיטית יותר), כדי שהנתונים ימשיכו לזרום, ובמקביל לשלוח התראה לצוות המהנדסים. תלות ב-API פנימי היא חרב פיפיות: מהירה מאוד, אבל שבירה מאוד.
מנתונים גולמיים למוצר: בניית API וייצוא נתונים
איסוף הנתונים הוא רק חצי מהעבודה. הנתונים הגולמיים, כפי שהם יושבים בבסיס הנתונים שלכם, הם לא שימושיים לרוב בעלי העניין. השלב האחרון והחשוב לא פחות הוא הפיכת המידע הזה למוצר נגיש. עבור לקוחות רבים, הדרישה היא לקבל API / קובץ נתונים מ-Medi-Link בצורה מסודרת ונקייה.
זה אומר לבנות שכבת API מעל בסיס הנתונים שלכם, עם תיעוד ברור, שתאפשר למערכות אחרות לצרוך את המידע. נקודות קצה נפוצות כוללות GET /products עם אפשרויות סינון ומיון, או GET /products/{id}/price_history כדי לראות שינויי מחיר לאורך זמן. לחלופין, עבור לקוחות פחות טכניים, תהליך אוטומטי שיוצר ייצוא יומי או שבועי של הנתונים לקובץ CSV או JSON ומעלה אותו ל-S3 bucket יכול להיות פתרון מצוין.
האתגר הטכני כאן הוא ניקוי וסטנדרטיזציה של הנתונים. המידע באתר המקור לא תמיד עקבי. יכולים להיות שמות מוצרים שונים מעט, קטגוריות מבולגנות, או פורמטים שונים של מפרטים. שלב ה-ETL (Extract, Transform, Load) שאחרי ה-scraping הוא המקום שבו אתם מוסיפים את הערך האמיתי, והופכים ערבוביה של HTML ו-JSON לסט נתונים מובנה ואיכותי. אם המערכת שלכם נתקלת בהרבה שגיאות 429, כדאי לקרוא את המדריך לטיפול בשגיאות 429 כדי לשפר את יציבות התהליך.
מתי לא כדאי להשתמש בגישה הזאת
למרות כל מה שכתבתי, הגישה של בניית scraper מורכב מאפס היא לא תמיד התשובה הנכונה. חשוב להיות כנים לגבי זה. אם הצורך שלכם הוא חד-פעמי, למשל, חילוץ רשימת מוצרים מקטגוריה אחת לצורך ניתוח שוק מהיר, בניית מערכת שלמה עם Playwright, proxies, וניהול סשנים היא over-engineering רציני. המאמץ הנדרש לפיתוח ותחזוקה פשוט לא מצדיק את התוצאה.
במקרים כאלה, פתרון ידני או שימוש בכלי פשוט יותר יכולים להספיק. לפעמים, אפילו תוסף לדפדפן יכול לעשות את העבודה עבור משימות קטנות. המורכבות שאנחנו מדברים עליה כאן רלוונטית כשאתם צריכים נתונים באופן עקבי, אמין ובקנה מידה גדול – למשל, ניטור יומי של 50,000 מוצרים. אם אתם לא שם, אתם עלולים לבזבז שבועות של פיתוח על בעיה שאפשר לפתור בשעתיים.
בנוסף, אם ל-Medi-Link היה API ציבורי ומתועד (מה שבדרך כלל אין לאתרי מסחר), השימוש בו תמיד יהיה עדיף על scraping. זה יהיה יציב יותר, מהיר יותר, וחוקי יותר מבחינת תנאי השימוש. תמיד בדקו אם קיימת אפשרות כזו לפני שאתם מתחילים לכתוב את השורה הראשונה של ה-scraper. הגישה המתוארת במאמר היא הפתרון כשאין דרך אחרת, לא כברירת מחדל.
