למה nadlan.gov.il הוא לא עוד אתר פשוט
נתחיל מהבסיס. אתרי ממשלה הם חיה אחרת. לפעמים הם בנויים על תשתית ישנה, ולפעמים הם משלבים SPA מודרני מבוסס React או Angular על גבי מערכות לגאסי. אתר הנדל״ן הממשלתי נופל איפשהו באמצע. ה-HTML הראשוני שתקבלו כמעט ריק מתוכן. הנתונים האמיתיים, כמו מחירי דירות ושמות מוצרים/מודעות, נטענים דינמית דרך קריאות API פנימיות שמופעלות על ידי JavaScript בדפדפן. ניסיון לגשת ישירות ל-API האלה הוא מסלול מהיר לחסימה. הם מצפים ל-headers ספציפיים, cookies, ואולי אפילו טוקנים שנוצרים on-the-fly.
האתגר השני הוא קנה המידה והמבנה. זה לא קטלוג מוצרים סטנדרטי. אנחנו מדברים על מאגר מידע של עסקאות, מכרזים ונכסים, עם עשרות אלפי רשומות שמתעדכנות באופן לא סדיר. המטרה של איסוף קטלוג הנדל״ן הממשלתי היא לא משימה חד-פעמית, אלא תהליך מתמשך של זיהוי שינויים. בניגוד לאתרי e-commerce, כאן אין מבנה עמודים לינארי וברור. הניווט מורכב, והגעה לכל פיסת מידע דורשת אינטראקציה מרובה עם פילטרים, כפתורים וטעינות אסינכרוניות. כל זה אומר שסקריפר פשוט מבוסס HTTP פשוט לא יראה את התמונה המלאה. הוא יקבל דף ריק וידווח על הצלחה, בזמן שהוא פספס 100% מהדאטה.
הארכיטקטורה הנכונה: למה צריך דפדפן אמיתי
אז אם requests בחוץ, מה כן עובד? התשובה היא חד משמעית: דפדפן אמיתי, אוטומטי. ותפסיקו עם Selenium לפרויקטים חדשים. Playwright מנצח אותו ב-2025 בכל מטריקה רלוונטית, ממהירות ועד יציבות ויכולות network interception. כשאתה עובד מול אתר כמו הנדל״ן הממשלתי, אתה צריך את היכולת לרנדר JavaScript, לטפל באירועים ולחכות לאלמנטים שנטענים אסינכרונית. כל זה מגיע out-of-the-box עם Playwright.
הגישה שלי מתחילה תמיד בבניית תהליך בסיסי שמדמה משתמש אמיתי. הוא מנווט לדף החיפוש, ממלא פילטרים, לוחץ על 'חפש', ומחכה שהתוצאות יופיעו. רק אז מתחיל החילוץ. היתרון הגדול הוא שאתה לא צריך לעשות reverse engineering מורכב ל-API הפנימי. הדפדפן עושה את העבודה הקשה. יתרה מזאת, שימוש בפיצ'רים מתקדמים יותר יכול לחסוך המון זמן. לדוגמה, במקום לחלץ את הנתונים מה-HTML המרונדר, אפשר להשתמש ב-Playwright כדי ליירט את תגובות ה-API. כך מקבלים JSON נקי ויפה ישירות מהמקור, בלי להתעסק עם סלקטורים של CSS שבירים. זה דורש קצת יותר עבודת setup, אבל התחזוקה לאורך זמן פשוטה משמעותית. אם אתם חדשים בתחום, יש מדריך Playwright stealth מצוין שיכניס אתכם לעניינים מהר.
איך מנהלים 50,000 בקשות ביום בלי להישרף
אחרי שיש לנו סקריפר שעובד על דף בודד, מגיע האתגר האמיתי: סקייל. הרצת אלפי בקשות ביום מ-IP בודד היא מתכון לאסון. אתרי ממשלה אולי לא משתמשים במערכות ההגנה הכי אגרסיביות, אבל הם בהחלט מנטרים התנהגות חריגה. הפתרון הוא כמובן proxy rotation. אבל לא כל proxy יעבוד. פרוקסי של דאטה סנטר ייחסם כמעט מיידית. צריך להשתמש ב-residential או mobile proxies כדי להיראות כמו תעבורה לגיטימית.
הכלל שלי הוא לא לעבור את ה-10 בקשות לדקה מאותו IP. זה אולי נשמע איטי, אבל עם מאגר של 200-300 IPs, אפשר להגיע לקצבים גבוהים מאוד במקביל. המטרה של ניטור מחירים הנדל״ן הממשלתי דורשת בדיקות תכופות, ולכן ניהול IP בריא הוא קריטי. אני משתמש במערכת שמנהלת את ה-pool, מזהה IPs ש'נשרפו' (מתחילים לקבל שגיאות 429 או CAPTCHA), ומוציאה אותם מהרוטציה ל-cooldown של כמה שעות. אם אתם רואים אחוזי שגיאה שעולים מעל 5%, זה סימן שהקצב שלכם אגרסיבי מדי או שאיכות ה-IPs ירדה. במקרים כאלה, צריך להבין איך לבחור פרוקסי residential שבאמת מתאים למשימה ולא רק נראה טוב על הנייר.
תרחיש הכשל: כשנתוני המכרזים נעלמים
בואו נדבר על failure mode ספציפי שראיתי קורה עם אתר הנדל״ן הממשלתי. אחד ה-use cases המרכזיים הוא מודיעין מתחרים הנדל״ן הממשלתי דרך ניתוח מכרזים. המערכת רצה יפה במשך חודשים, שואבת נתונים על מכרזים חדשים, סטטוסים ומחירים. יום אחד, מספר המכרזים החדשים צונח לאפס. אין שגיאות, הסקריפר מדווח על ריצה מוצלחת של 100%, אבל הדאטהבייס פשוט לא מתעדכן. מה קרה?
אחרי כמה שעות של דיבאגינג, התברר שהם שינו את ה-payload של בקשת ה-API הפנימית שמביאה את רשימת המכרזים. הם הוסיפו פרמטר חדש, sessionToken, שלא היה שם קודם. הסקריפר שלנו המשיך לשלוח את הבקשה הישנה, והשרת, במקום להחזיר שגיאת 400 (Bad Request), פשוט החזיר מערך ריק [] עם סטטוס 200 (OK). זהו כשל שקט ומסוכן. הוא לא מפעיל התראות כי טכנית, לא הייתה שגיאה. הלקח כאן הוא קריטי: אי אפשר לסמוך רק על status codes. חייבים להוסיף validation לשלב ה-parsing. תמיד לוודא שהדאטה שחולץ תואם לסכמה הצפויה, ושהוא לא ריק באופן חשוד. אם סקריפר שאמור להביא עשרות תוצאות פתאום מחזיר אפס, זו צריכה להיות שגיאה קריטית שמפעילה התראה מיידית. זה ההבדל בין מערכת חובבנית למערכת production-grade.
מתי הגישה הזו היא Overkill
אחרי כל זה, חשוב לשמור על פרופורציה. האם כל פרויקט שקשור ל-nadlan.gov.il דורש Playwright, מאגר residential proxies ו-data validation מורכב? לא. אם כל מה שאתה צריך זה לבדוק פעם ביום סטטוס של שניים-שלושה מכרזים ספציפיים, כל הסטאק הזה הוא בזבוז מאמץ אדיר. במקרה כזה, סקריפט פשוט שירוץ לכם על המחשב פעם ביום כנראה יספיק. סביר להניח שלא תיחסמו על נפח תעבורה כל כך נמוך.
הארכיטקטורה שתיארתי מיועדת לקנה מידה גדול. היא נכנסת לפעולה כשאתם צריכים לבנות API / קובץ נתונים הנדל״ן הממשלתי מקיף ומתעדכן. כלומר, כשאתם צריכים לחלץ אלפי רשומות ביום, לנטר שינויים בזמן אמת, ולהבטיח שהנתונים שלכם מדויקים ואמינים לאורך חודשים ושנים. אם הדרישה היא מעקב מלאי/זמינות הנדל״ן הממשלתי על כל הנכסים הפעילים, אין דרך לעקוף את המורכבות. אבל לפרויקט קטן ונקודתי? אל תבנו F-35 כדי לנסוע למכולת. תתחילו פשוט, ותוסיפו את השכבות הנוספות רק כשהצורך והסקייל ידרשו זאת. לפעמים, הפתרון הפשוט ביותר הוא הנכון, גם אם הוא פחות 'מרשים' טכנולוגית. זה שיקול הנדסי חשוב שלפעמים נשכח.
מהנתונים הגולמיים למוצר דאטה שמיש
חילוץ הנתונים הוא רק חצי מהקרב. השלב הבא, והחשוב לא פחות, הוא להפוך את ה-JSON הגולמי שקיבלתם למשהו שאפשר לעבוד איתו. זה כולל ניקוי, נרמול, והעשרה. לדוגמה, שדות כתובת באתר הנדל״ן הממשלתי יכולים להגיע בפורמטים לא עקביים. תצטרכו לכתוב לוגיקה שמפרקת את הכתובת לרכיבים (עיר, רחוב, מספר) ומנרמלת אותם. שדות תאריך עשויים להגיע כסטרינגים בעברית, ותצטרכו להמיר אותם לפורמט ISO סטנדרטי.
בפרויקטים גדולים, אנחנו בונים צינור עיבוד נתונים (data pipeline) שעושה את כל זה אוטומטית. כל רשומה חדשה שנכנסת עוברת סדרה של שלבי validation ו-transformation לפני שהיא נשמרת בדאטהבייס הסופי. זה המקום שבו גם מטפלים בכפילויות. למשל, אם אותו נכס מופיע שוב בסריקה הבאה, המערכת צריכה לזהות זאת ולעדכן את הרשומה הקיימת במקום ליצור חדשה. השקעה ב-pipeline נקי וחזק חוסכת שבועות של עבודת ניקוי ידנית בהמשך הדרך. אם אתם מתמודדים עם חסימות כמו Cloudflare באתרים אחרים, כדאי לקרוא את המדריך לעקיפת Cloudflare שמכסה אסטרטגיות דומות.
