למה Scraping נתיבי ישראל שונה מכל אתר אחר
רובנו רגילים לרוץ על אתרי קמעונאות. המטרה שם היא מהירות, היקף, ועקיפת הגנות מתוחכמות. אבל כשניגשים לאתר כמו נתיבי ישראל, כללי המשחק משתנים. פה, הבעיה היא לא חסימה אחרי 1000 בקשות, אלא מבנה ה-DOM שמשתנה בין קטגוריות בלי שום היגיון. פרויקט אחד יוצג בטבלה, אחר ברשימת div-ים, והשלישי בכלל יהיה קבור בתוך iframe. המטרה המרכזית היא בדרך כלל איסוף קטלוג נתיבי ישראל של פרויקטים או מכרזים פעילים. גיליתי ש-CSS selectors שנכתבו ביום שני יכולים להפסיק לעבוד ברביעי, לא בגלל פריסה חדשה אלא בגלל שהעורך התורן החליט להדביק טבלה מוורד.
האתר לא בהכרח ינסה לחסום אותך באופן אקטיבי כמו אתר מסחרי. במקום זה, הוא יכשל אותך עם חוסר עקביות. למשל, ניסינו פעם לחלץ את כל המכרזים הפעילים באמצעות סקריפט פשוט. במשך שבועיים זה עבד, עד שהם הוסיפו מכרז חדש שהכיל תו מיוחד בשם הקובץ המצורף, מה ששבר את כל לוגיקת הפארסינג שלנו. ה-latency יכול לקפוץ מ-300ms ל-5 שניות לדף בודד רק בגלל שהשרת מנסה לייצר איזה דוח ישן. אתה לא נלחם פה ב-bot detection מתוחכם, אתה נלחם באנטרופיה.
הסטאק הנכון לעבודה: למה Playwright מנצח כאן
תשכחו מ-requests. פשוט תשכחו מזה. אם אתם מתחילים פרויקט חדש על נתיבי ישראל ב-2025, ברירת המחדל חייבת להיות כלי מבוסס דפדפן. אני מעדיף את Playwright על פני כל השאר. למה? כי חלק גדול מהמידע הקריטי באתר לא קיים ב-HTML הסטטי הראשוני. הוא נטען דינמית באמצעות JavaScript אחרי שהדף עולה. ראיתי טבלאות מכרזים שלמות שפשוט לא קיימות במקור הדף, והן מופיעות רק אחרי שהמשתמש לוחץ על פילטר מסוים או גולל למטה.
תרחיש כשלון קלאסי שנתקלתי בו: בנינו scraper מבוסס requests כדי לעקוב אחר עדכונים במכרזים. הוא עבד מעולה עד שצוות הפיתוח של האתר החליף את טבלת ה-HTML הפשוטה ברכיב React שמושך את הנתונים מ-endpoint פנימי. הסקריפט שלנו התחיל להחזיר דפים ריקים, וההתראות לא פעלו. לקח לנו יומיים להבין שהבעיה היא לא חסימה, אלא שינוי טכנולוגי. עם Playwright, המעבר היה כמעט שקוף כי הוא מריץ דפדפן אמיתי ומחכה שהתוכן יופיע. הזמן הנוסף שלוקח לרינדור הדף, לפעמים עד 2-3 שניות, הוא מחיר קטן לשלם עבור אמינות. זה ההבדל בין data pipeline שעובד 99.9% מהזמן לאחד שנופל כל חודש. אם אתם עדיין לא שולטים בו, יש מדריך Playwright stealth מצוין שיכניס אתכם לעניינים.
מודיעין מתחרים בזמן אמת: מעקב אחר מכרזים
אחד ה-use cases המרכזיים עבור אתר כזה הוא מודיעין מתחרים נתיבי ישראל. חברות שמתמודדות במכרזים רוצות לדעת מיד כשמכרז חדש מתפרסם, כשמועד הגשה משתנה, או כשמתפרסם מסמך שאלות ותשובות. המידע הזה קריטי. המטרה היא לא לסרוק את כל האתר כל הזמן, אלא לבצע בדיקות ממוקדות ומהירות. אנחנו לא צריכים 50 בקשות בשנייה. מספיק לבדוק את עמוד המכרזים הראשי כל 10-15 דקות.
האתגר הוא לא הקצב, אלא הפארסינג. צריך לבנות לוגיקה שיודעת לזהות שינויים עדינים. למשל, אנחנו לא רק מחלצים שדות כמו שמות מוצרים/מודעות (במקרה הזה, שמות המכרזים), אלא גם מחשבים hash על קבצי ה-PDF המצורפים. אם ה-hash של מסמך המפרט משתנה, אנחנו שולחים התראה מיידית, גם אם שום טקסט אחר בעמוד לא השתנה. זה דורש מערכת שיודעת לשמור state. בנוסף, למרות שהאתר לא אגרסיבי, עדיין מומלץ להשתמש ב-proxy rotation בסיסי כדי למנוע חסימות על בסיס IP. לא צריך רשת ענקית, אבל כן כדאי לדעת איך לבחור פרוקסי residential איכותי כדי להבטיח שהסקריפט ימשיך לרוץ בלי הפרעות.
מ-Scraping מבולגן ל-API נקי
המטרה הסופית היא לא סתם לאסוף HTML. המטרה היא לייצר API / קובץ נתונים נתיבי ישראל נקי, עקבי ושימושי שהמערכות הפנימיות שלנו יכולות לצרוך. זה השלב שבו רוב הפרויקטים נופלים. קל לחלץ נתונים, קשה להפוך אותם למוצר. ה-scraper שלנו צריך לנקות את הנתונים, לתקן שגיאות נפוצות (למשל, תאריכים בפורמטים שונים), ולהעשיר אותם. לדוגמה, אנחנו מזהים אוטומטית מספרי פרויקטים בטקסט חופשי ומקשרים אותם לרשומות אחרות במאגר הנתונים שלנו. התוצר הסופי הוא לא קובץ CSV מבולגן, אלא endpoint של API שמחזיר JSON מובנה היטב, או קובץ Parquet יומי עם סכמה קבועה.
זה דורש תכנון. צריך לחשוב על data validation, על טיפול בשגיאות, ועל מנגנון ניטור. אנחנו משתמשים בסכמה קפדנית (כמו Pydantic ב-Python) כדי לוודא שכל רשומה עומדת בסטנדרט שהגדרנו. אם ה-scraper פתאום מתחיל להחזיר ערכי null בשדה שהיה תמיד מלא, המערכת מפעילה התראה. בניית ה-pipeline הזה היא 80% מהעבודה, וה-scraping עצמו הוא רק 20%. זה הופך אוסף של סקריפטים שבירים למערכת דאטה אמינה.
אבל רגע, מתי הגישה הזו מיותרת?
אני תמיד טוען שצריך להתאים את הכלי למשימה. למרות כל מה שאמרתי, לא תמיד צריך להפעיל את התותחים הכבדים של Playwright ו-data pipeline מורכב. אם כל מה שאתם צריכים זה לבדוק פעם בחודש אם פרויקט ספציפי עדיין מופיע באתר, סקריפט requests פשוט עם התראה במייל יעשה את העבודה. אין טעם לבנות מערכת שלמה עבור משימה חד-פעמית או כזו שרצה בתדירות נמוכה מאוד.
המורכבות שאני מתאר נחוצה כשאתם בונים מוצר נתונים שמיועד לשימוש ארוך טווח, כשהאמינות והעקביות הן קריטיות. זה רלוונטי עבור ניטור מחירים נתיבי ישראל במכרזים, או למערכות שדורשות עדכונים שוטפים. אבל אם אתם צריכים רק תמונת מצב חד-פעמית לצורך אנליזה, אל תסבכו את החיים. כתבו סקריפט פשוט, הריצו אותו, קחו את הנתונים ותזרקו את הקוד. לפעמים, הפתרון המהיר והמלוכלך הוא הפתרון הנכון. לדעת מתי לבחור בגישה הזו זה סימן לניסיון, לא לעצלנות. לא כל בעיה דורשת פתרון בקנה מידה תעשייתי.
