למה אתר ממשלתי הוא חיה אחרת לגמרי
בואו נשים את זה על השולחן. כשאתה עושה scraping לאתר כמו משרד התחבורה, אתה לא נלחם במערכות anti-bot מתוחכמות כמו באתרי טיסות או סניקרס. האויב שלך הוא לא Cloudflare או Akamai, אלא אנטרופיה. המערכות הממשלתיות מורכבות מטלאים של מכרזים שונים לאורך שנים, מה שיוצר חוסר עקביות מובנה. דף אחד יכול להיות מבוסס ASP.NET קלאסי עם ViewState, ואילו עמוד אחר באותו דומיין יכול להיות SPA מודרני שמדבר עם API פנימי.
האתגר הראשון הוא Discovery. אתה צריך למפות את האתר לא רק ברמת ה-URLs, אלא ברמת הטכנולוגיות. האם המידע שאתה צריך נמצא ב-HTML סטטי? האם הוא נטען דרך XHR request אחרי אינטראקציה של המשתמש? האם הוא קבור בתוך PDF שנוצר דינמית? כל תרחיש כזה דורש סט כלים שונה. ראיתי פרויקטים שכשלו כי הצוות הניח שכל האתר עובד באותה צורה. הם בנו scraper מבוסס requests רק כדי לגלות ש-70% מהמידע החשוב נטען דרך JavaScript. זה בזבוז זמן ומשאבים שאפשר למנוע עם מיפוי נכון בהתחלה.
איסוף קטלוג ובניית API: ה-Use Cases המרכזיים
שני ה-use cases העיקריים שאנחנו רואים סביב אתר משרד התחבורה הם 'איסוף קטלוג' ו-'בניית API / קובץ נתונים'. נפרק אותם.
איסוף קטלוג הוא לא רק על רכבים. זה יכול להיות איסוף של כל תקנות התעבורה, רשימת קווי שירות בתחבורה ציבורית, או מפרטים של דגמי רכב חדשים שאושרו לייבוא. המטרה היא לקחת מידע לא מובנה ולהפוך אותו לדאטה-סט מסודר עם שדות כמו שמות מוצרים/מודעות וקטגוריות. לדוגמה, חילוץ כל דגמי הרכב עם רמת זיהום אוויר מתחת לסף מסוים. זה דורש זחילה של מאות, לפעמים אלפי דפים, ופרסור של טבלאות HTML מסורבלות או מסמכים מצורפים.
בניית API / קובץ נתונים לוקחת את זה צעד קדימה. במקום דאטה-סט סטטי, המטרה היא ליצור פיד חי. למשל, API שמספק את מועדי המבחן הפנויים הקרובים ביותר לטסטים. זהו כבר לא batch job שרץ פעם ביום, אלא תהליך שצריך לרוץ בתדירות גבוהה, לדמות אינטראקציה עם טפסים (בחירת עיר, סוג מבחן) ולחלץ זמינות כמעט בזמן אמת. פה, טיפול בשגיאות 429 והגבלות קצב הופך להיות קריטי, גם אם מדובר באתר ממשלתי שלא מנסה לחסום אותך באופן אקטיבי.
תרחיש הכשל הנפוץ: ניהול סשנים ו-ViewState
הנה תרחיש שראיתי קורה יותר מדי פעמים בפרויקטים מול אתרים ממשלתיים. המהנדס בונה סקרייפר שמנווט בין דפים, ממלא טופס חיפוש ומקבל תוצאות. הכל עובד נהדר על המחשב שלו. אבל כשהוא מריץ את זה על שרת, בקנה מידה גדול, הוא מתחיל לקבל דפים ריקים או הודעות שגיאה על 'סשן לא תקין'.
הבעיה? הוא התעלם מ-state. אתרים רבים שנבנו בטכנולוגיות ותיקות כמו ASP.NET Web Forms מסתמכים בכבדות על ViewState ועל קוקיות סשן כדי לעקוב אחר תהליך הניווט של המשתמש. ה-ViewState הוא בלוק טקסט מקודד ב-base64 שמוטמע ב-HTML ומכיל את כל המצב של הדף. אם אתה מנסה לשלוח POST request לדף הבא בתהליך בלי ה-ViewState הנכון מהדף הקודם, השרת פשוט יזרוק אותך. זה לא באג, זה פיצ'ר.
הפתרון הוא לא לזרוק את כל הלוגיקה ולהשתמש בדפדפן מלא כמו Playwright (למרות שלפעמים זה הכרחי). הפתרון הנכון הוא להבין את המנגנון. צריך לנהל סשן HTTP (עם requests.Session בפייתון, למשל), לחלץ את ה-ViewState וכל שדה חובה נסתר אחר מה-HTML של כל שלב, ולשלוח אותם ב-payload של הבקשה הבאה. זה הופך את הסקרייפר למורכב יותר, אבל גם ליעיל ואמין פי 1000. סקרייפר כזה יכול להריץ 50-100 בקשות בשנייה, בעוד שפתרון מבוסס דפדפן יתקשה לעבור את ה-2-3 בקשות בדקה לאותו תהליך.
מתי חובה להשתמש בדפדפן מלא (Headless)
אמרתי קודם לא למהר לדפדפן מלא, אבל יש גבול. יש נקודה שבה ההנדסה ההפוכה של בקשות ה-API הפנימיות של האתר הופכת למאמץ גדול יותר מתחזוקת כמה מופעים של Chrome headless. אם המידע שאתה צריך מופיע רק אחרי שרשרת של 5-6 אינטראקציות JavaScript מורכבות, או אם הוא מוצג על גבי מפה אינטראקטיבית שנטענת מקומפוננט צד-שלישי, זה הזמן לעצור. אל תבזבז שבוע בניסיון לפענח לוגיקה עסקית מתוך קוד JavaScript שעבר minification.
כאן Playwright נכנס לתמונה. ובאופן ספציפי, שימוש בו נכון. זה לא רק עניין של page.goto() ו-page.content(). צריך לבנות את הלוגיקה סביב המתנה לאלמנטים ספציפיים, יירוט של בקשות רשת רלוונטיות, וניהול נכון של משאבים. למשל, במקום לחכות לטעינה מלאה של הדף, אפשר ליירט את בקשת ה-XHR שמביאה את הנתונים ולחסוך זמן עיבוד יקר. זה קריטי כשמדובר על 'מעקב מלאי/זמינות' של שירותים, שם כל שנייה חשובה. המעבר לדפדפן מלא מגדיל את המורכבות התפעולית, אבל הוא פותח דלת לנתונים שפשוט אי אפשר להגיע אליהם אחרת. אם כבר בחרתם בדרך הזו, תשקיעו בלהבין את הפיצ'רים המתקדמים. קראו את ה-מדריך Playwright stealth כדי לוודא שהאוטומציה שלכם לא מזוהה בקלות.
ניטור שינויים ומודיעין: מעבר מאיסוף חד-פעמי לתחזוקה
הצלחת לבנות סקרייפר שעובד. מעולה. חלצת 50,000 רשומות על דגמי רכב. מה עכשיו? העבודה האמיתית רק מתחילה. הערך הגדול בנתונים האלה הוא לא בצילום מצב חד-פעמי, אלא במעקב אחר השינויים לאורך זמן. זה מה שמבדיל פרויקט חובבני ממערכת דאטה מקצועית.
השלב הבא הוא לבנות מנגנון diff. בכל הרצה, השווה את הנתונים החדשים עם הנתונים מההרצה הקודמת. אילו רשומות נוספו? אילו הוסרו? באילו רשומות השתנו ערכים ספציפיים? זה הבסיס למה שניתן לכנות 'מודיעין מתחרים' בהקשר הממשלתי - מעקב אחר שינויי מדיניות, עדכון תקנות, או הוספת שירותים חדשים. לדוגמה, התראה אוטומטית כשמשרד התחבורה מוסיף סוג רישיון חדש או משנה את דרישות הבטיחות לרכב מסחרי.
בניית מערכת כזו דורשת חשיבה על ארכיטקטורה. אתה צריך מקום לאחסן את ה-snapshot הקודם, לוגיקה להשוואה, ומערכת התראות. בנוסף, הסקרייפר שלך חייב להיות עמיד לשברים. מה קורה אם מבנה ה-HTML משתנה? הסקרייפר לא אמור לקרוס, אלא לזהות את השינוי, לדווח עליו, ולהיכנס למצב תחזוקה. השקעה ב-איך לבחור פרוקסי residential יכולה לעזור גם כאן, לא רק למניעת חסימות אלא לפיזור הבקשות ולהבנת תגובות שונות מאזורים גיאוגרפיים שונים, אם רלוונטי.
