למה Scraping של דן שונה מאתר E-commerce סטנדרטי

באתר קמעונאות, קטלוג המוצרים הוא יחסית יציב. מחיר משתנה, מלאי מתעדכן, אבל המוצר עצמו נשאר. בדן, ה"מוצרים" הם נסיעות — ישויות דינמיות שתלויות בזמן. לוח הזמנים הוא הקטלוג, והוא משתנה. משימה כמו איסוף קטלוג דן היא לא פעולה חד-פעמית, אלא תהליך מתמשך של ניטור שינויים בנתיבים, תחנות ושעות. המידע הזה מוצג לרוב דרך רכיבי JavaScript אינטראקטיביים, מה שהופך סקרייפרים מבוססי HTTP פשוטים לחסרי תועלת. הם יקבלו שלד HTML ריק מתוכן.

כאן נכנס לתמונה Playwright. תפסיקו עם Selenium לפרויקטים חדשים. Playwright מנצח אותו ב-2025 בכל מטריקה רלוונטית, במיוחד בביצועים וב-API. היכולת שלו לחכות לאלמנטים ספציפיים או לבקשות רשת היא קריטית כאן. אתה לא יכול פשוט 'לטעון את הדף'; אתה צריך לדמות אינטראקציה של משתמש — בחירת מוצא, יעד ותאריך — כדי לגרום לאפליקציית ה-frontend לבצע את הקריאות לרשת ולהציג את הנתונים הרלוונטיים. כל ניסיון לחסוך פה במורכבות ולהשתמש בכלי פשוט יותר יוביל לשעות של דיבאגינג וכישלונות שקטים כשה-frontend ישתנה במעט.

למצוא את ה-API הנסתר: הדרך המהירה לנתונים

אחרי שהבנו שצריך headless browser, הצעד הבא הוא לנסות להיפטר ממנו כמה שיותר מהר. רינדור מלא של דפים הוא בזבוז משאבים. הזהב האמיתי נמצא בבקשות ה-XHR/Fetch שהדפדפן מבצע ברקע. פתחו את ה-DevTools, עברו לטאב Network, ובצעו חיפוש באתר. אתם תראו קריאות ל-endpoints של API שמחזירות JSON נקי. זה המקור שלכם.

במקום לפרסר HTML שביר, אתם מקבלים אובייקטים מובנים עם כל מה שצריך: מספרי קווים, שעות יציאה, מחירים, וחשוב מכל, זמינות מושבים. זה משנה את כל המשחק עבור Use Case כמו API / קובץ נתונים דן. במקום לבנות פארסר מורכב, אתם בונים לקוח API. העבודה עוברת מכתיבת סלקטורים של CSS לניתוח מבנה התגובה של ה-API. זה גם מהיר פי 10 לפחות. קריאת API ישירה לוקחת אולי 300ms, בעוד טעינה ורינדור מלא של דף ב-Playwright יכולה לקחת 3-5 שניות. כשאתה צריך לסרוק אלפי קווים ביום, ההבדל הזה מצטבר. כמובן שזה דורש תחזוקה. אם ה-API משתנה, הסקרייפר שלכם נשבר. אבל זה trade-off שאני מוכן לקחת כל יום.

התרחיש שבו סקרייפרים של קווי אוטובוס נופלים

הנה failure mode קלאסי שראיתי בפרויקטים של ניטור תחבורה: הסתמכות יתר על caching. נניח שבניתם סקרייפר שעובר על כל הקווים של דן פעם ביום כדי לעדכן לוחות זמנים. זה נשמע סביר, נכון? אבל מה קורה אם יש עבודות תשתית דחופות וקו 51 משנה את המסלול שלו לשש השעות הקרובות? המערכת שלכם, שמסתמכת על נתונים מלפני 8 שעות, תספק מידע שגוי למשתמשים. במקרה הטוב זו אי נוחות, במקרה הרע זה גורם למישהו לפספס פגישה חשובה.

הטעות היא להתייחס לכל המידע כשווה ערך. מידע על מסלול קו יכול להיות ב-cache למשך כמה שעות, אבל מעקב מלאי/זמינות דן בזמן אמת דורש גישה אחרת. זמינות מושבים בנסיעה ספציפית צריכה להיבדק ב-TTL (Time To Live) של דקה, לא יותר. זה דורש ארכיטקטורה מתוחכמת יותר, שמפרידה בין סוגי המידע השונים ומעדכנת אותם בקצבים שונים. זה גם אומר שאי אפשר פשוט להריץ batch job פעם ביום. צריך מערכת שמסוגלת לבצע שאילתות נקודתיות ומהירות לפי דרישה. מי שלא בונה את ההפרדה הזו, בונה מערכת שתספק נתונים שגויים. זו לא שאלה של אם, אלא מתי.

אבל רגע, זה לא עובד בלי תשתית נכונה

כל מה שדיברנו עליו נשמע טוב בתיאוריה, אבל אם תנסו להריץ אלפי בקשות מה-IP של השרת שלכם, אתם תחטפו חסימה. מהר. אתרים כמו דן, גם אם אין להם הגנות מתוחכמות כמו Cloudflare, עדיין מפעילים rate limiting בסיסי. 200 בקשות מהירות מאותו IP תוך דקה הן דגל אדום ברור. לכן, פרויקט רציני של מודיעין מתחרים דן או ניטור מחירים דורש תשתית פרוקסי חכמה.

אני לא מדבר על רשימה של 10 פרוקסים חינמיים שמצאתם ברשת. אני מדבר על pool של מאות או אלפי residential proxies. חשוב להבין את ההבדל: איך לבחור פרוקסי residential מסביר את זה לעומק, אבל הנקודה היא שאתם צריכים להיראות כמו תנועה של משתמשים אמיתיים ממקומות שונים. בנוסף, חשוב לנהל את ה-sessions בצורה נכונה. אם כל בקשה ל-API מגיעה מ-IP אחר, זה חשוד. גישה טובה יותר היא להשתמש ב-sticky sessions, כך שרצף של בקשות ששייכות לאותו 'משתמש' מגיע מאותו IP למשך מספר דקות. זה דורש לוגיקה בצד הלקוח, אבל זה מה שמפריד בין סקרייפר עם 60% הצלחה לכזה שמגיע ל-99.5%.

מבנה הנתונים והיצוא: מה באמת מעניין את הלקוח

בסופו של דבר, המטרה היא לספק נתונים שמישים. אף אחד לא רוצה לקבל dump של HTML. המטרה היא לספק ייצוא CSV/API יומי או שבועי שמכיל מידע נקי ומובנה. אחרי שחילצתם את הנתונים, בין אם מ-HTML או JSON, העבודה רק מתחילה. צריך לנרמל את המידע. למשל, שמות של תחנות יכולים להופיע בכמה וריאציות. צריך למפות אותם לייצוג קנוני אחד. צריך לטפל בערכי קצה, כמו נסיעות שהתבטלו או מחירים שלא זמינים.

הפלט הסופי צריך להיות מתוכנן היטב. טבלת CSV פשוטה יכולה להתאים לניתוח ראשוני, אבל לקוח רציני ירצה גישה ל-API משלכם, שיאפשר לו לשלוף את המידע העדכני ביותר לפי פרמטרים. לדוגמה, שאילתה שתחזיר את כל שינויי המחיר ב-24 השעות האחרונות בקו ספציפי. בניית ה-API הזה היא חלק בלתי נפרד מפרויקט ה-scraping. זה מה שהופך אוסף של סקריפטים למוצר נתונים אמיתי. אם אתם מתכננים פרויקט ניטור מחירים דן, תחשבו מההתחלה איך הנתונים האלה ייראו ואיך יצטרכו לצרוך אותם. זה יחסוך לכם שכתובים יקרים בהמשך הדרך.