למה Requests פשוט לא יספיק לכם בתן ביס
בואו נשים את זה על השולחן: אם הגישה הראשונית שלכם היא להשתמש בספריית HTTP פשוטה כמו requests, אתם תבזבזו שעות ותקבלו דאטה חסר ערך. האתר של תן ביס הוא לא אוסף של דפים סטטיים. התוכן שאתם רואים תלוי לחלוטין בהקשר – כלומר, בכתובת שהזנתם. בלי כתובת, אין רשימת מסעדות. בלי סשן פעיל, אין תפריטים רלוונטיים.
זהו ה-failure scenario הקלאסי בפלטפורמות כאלה. מפתח מנסה לשלוף את ה-HTML של עמוד מסעדה, ומקבל בחזרה דף גנרי או דף שמבקש ממנו להזין כתובת. למה? כי התוכן, כולל זמינות המסעדות והתפריטים, מרונדר בצד הלקוח באמצעות JavaScript לאחר סדרה של קריאות API פנימיות. קריאות אלו דורשות טוקנים, קוקיז ו-headers שנוצרים רק בסביבת דפדפן אמיתית. כל ניסיון לחקות את הלוגיקה הזו ידנית יהפוך לקרב מתמשך מול שינויים ב-API הפנימי שלהם.
לכן, נקודת הפתיחה חייבת להיות כלי שמריץ דפדפן מלא. תפסיקו עם Selenium לפרויקטים חדשים. Playwright מנצח אותו ב-2025 בכל מטריקה רלוונטית, במיוחד בביצועים וב-API האסינכרוני שלו. הוא מאפשר לכם לדמות את כל האינטראקציה האנושית: הזנת כתובת, המתנה לטעינת הרכיבים הדינמיים, ורק אז – חילוץ המידע. זה הבסיס ההכרחי לכל פעולת scraping רצינית באתר כמו תן ביס.
ארכיטקטורה לאיסוף קטלוג מלא: מעבר לסקריפט הבודד
אחרי שהבנו שחייבים דפדפן, השלב הבא הוא תכנון המערכת. המטרה היא איסוף קטלוג תן ביס המלא, שכולל אלפי מסעדות ועשרות אלפי פריטים. סקריפט בודד שמורץ על מכונה אחת פשוט לא יספיק. אנחנו מדברים על תהליך שיכול לקחת שעות, וצריך להיות עמיד לתקלות.
הארכיטקטורה שאני מעדיף מבוססת על תורים (Queues). יש לנו שלושה רכיבים עיקריים:
- Producer: תפקידו הוא לגלות את כל המסעדות הזמינות עבור רשימת כתובות מוגדרת מראש. הוא מזין כתובת, גולל עד סוף הרשימה, אוסף את כל ה-URLs של המסעדות ודוחף אותם לתור מסעדות (למשל, RabbitMQ או Redis).
- Restaurant Consumers: קבוצת workers שמאזינה לתור המסעדות. כל worker שולף URL של מסעדה, מנווט אליה עם Playwright, וחולץ את כל נתוני התפריט: קטגוריות, שמות מוצרים, תיאורים וגם מבצעים ייחודיים. לאחר החילוץ, הנתונים המובנים נדחפים לתור נתונים.
- Data Writer: worker בודד שמאזין לתור הנתונים וכותב אותם בצורה אטומית לבסיס הנתונים (PostgreSQL, MongoDB, וכו'). הפרדת הכתיבה מונעת צווארי בקבוק ומקלה על ניהול שגיאות בכתיבה.
גישה זו מאפשרת סקיילביליות אופקית. אם הסריקה איטית מדי, פשוט מוסיפים עוד workers מסוג Restaurant Consumer. הצלחנו להגיע עם ארכיטקטורה כזו לקצב של כ-500-600 מסעדות בדקה עם 20 workers במקביל, תוך שמירה על שיעור הצלחה של מעל 98%.
ניהול פרוקסי וטביעות אצבע: איך לא להיחסם אחרי 100 בקשות
בואו נדבר על הגנות. אתר בסדר גודל של תן ביס לא יושב ומחכה שיעשו לו scraping. הם משתמשים במערכות הגנה שמזהות התנהגות אוטומטית. חסימת IP היא הבעיה הראשונה שתתקלו בה, אבל היא רק קצה הקרחון.
הפתרון מתחיל בניהול פרוקסי חכם. פרוקסי מ-Data Center הם זולים אבל קלים לזיהוי. לרוב, תצטרכו להשתמש ב-Residential Proxies כדי שהתעבורה שלכם תיראה כאילו היא מגיעה ממשתמשים ביתיים אמיתיים. אבל גם זה לא מספיק. צריך לבצע רוטציה חכמה. אל תחליפו IP על כל בקשה – זה חשוד. החליפו IP כל כמה דקות או אחרי מספר מסוים של פעולות כדי לדמות סשן של משתמש אמיתי. המפתח הוא להבין את המנגנונים בצד השני; איך לבחור פרוקסי residential טוב הוא קריטי כאן.
מעבר ל-IP, יש את טביעת האצבע של הדפדפן (Browser Fingerprint). מערכות כמו Cloudflare או Akamai לא מסתכלות רק על ה-IP שלכם. הן בודקות עשרות פרמטרים: רזולוציית מסך, פונטים מותקנים, גרסת הדפדפן, התנהגות העכבר ועוד. שימוש ב-Playwright רגיל ישאיר טביעת אצבע רובוטית ברורה. כאן נכנסים כלים כמו playwright-extra עם תוסף ה-stealth שלו. הוא מבצע שינויים קטנים ב-headless browser כדי להפוך אותו לכמעט בלתי ניתן לזיהוי. אם אתם לא מטפלים ב-fingerprinting, אתם פשוט תתקלו ב-CAPTCHA אחרי 15 דקות עבודה.
מודיעין מתחרים וניטור שינויים בזמן אמת
אז יש לנו את הדאטה. מה עושים איתו? כאן נכנסים מקרי השימוש המתקדמים. מודיעין מתחרים תן ביס הוא אחד המרכזיים. רשתות מזון גדולות רוצות לדעת אילו מבצעים המתחרים מריצים, מהם זמני המשלוח הממוצעים באזורים שונים, ואילו מסעדות חדשות מצטרפות לפלטפורמה. מערכת ה-scraping שבנינו מספקת את חומר הגלם לניתוחים האלה.
ניטור מחירים תן ביס הוא עוד מקרה שימוש קריטי, אבל לא רק במובן של עליית מחיר. אנחנו עוקבים אחרי שינויים עדינים יותר: מנה שהייתה זמינה ועכשיו לא, שינוי ברכיבים, או הוספת אפשרויות חדשות. מערכת טובה תשמור היסטוריה של כל פריט ותפריט, ותאפשר להפיק התראות על שינויים משמעותיים. לדוגמה, זיהוי אוטומטי של מבצע "1+1" חדש במסעדה פופולרית יכול להיות מידע בעל ערך אדיר לרשת מתחרה.
האתגר הגדול ביותר כאן הוא תדירות ודיוק. סריקה יומית היא בסיס טוב, אבל עבור מעקב מלאי/זמינות תן ביס, לעיתים נדרשת דגימה גבוהה יותר, במיוחד בשעות העומס. בנינו מערכת שמסוגלת לבצע סריקות ממוקדות על מסעדות ספציפיות כל 15-30 דקות כדי לעקוב אחר שינויי זמינות של מנות פופולריות. זה דורש תכנון זהיר של תשתית כדי לא להעמיס על האתר או על המערכת שלנו. אם אתם נתקלים בחסימות תכופות, סביר להניח שקצב הבקשות שלכם גבוה מדי, וזה הזמן ללמוד על טיפול בשגיאות 429 בצורה נכונה.
מתי Scraping הוא לא הפתרון הנכון
אחרי כל מה שאמרתי, חשוב להיות כנים. יש מצבים שבהם בניית scraper מורכב לתן ביס היא פשוט לא הגישה הנכונה. זה לא פתרון קסם לכל בעיה. אם כל מה שאתם צריכים זה תפריט של חמש מסעדות ספציפיות פעם בחודש, המאמץ ההנדסי של בניית ותחזוקת מערכת אוטומטית כנראה לא מצדיק את עצמו. במקרה כזה, איסוף ידני הוא מהיר ויעיל יותר.
המורכבות האמיתית היא בתחזוקה. אתרים כמו תן ביס משנים את ה-UI וה-HTML שלהם כל הזמן. סלקטור שהיה יציב היום, עלול להישבר מחר בעקבות עדכון קטן. אם אין לכם צוות שיכול להקדיש זמן לתחזוקה שוטפת, לניטור שגיאות ולתיקון ה-scrapers, המערכת שלכם תהפוך מהר מאוד ללא רלוונטית. ראיתי פרויקטים גדולים נכשלים לא בגלל אתגר טכנולוגי ראשוני, אלא בגלל שלא תכננו את מאמץ התחזוקה הנדרש בטווח הארוך.
בנוסף, אם אתם מחפשים פתרון של API / קובץ נתונים תן ביס וצריכים נתונים נקיים ומובנים בלי להתעסק עם כל כאב הראש של התחזוקה, בניית scraper מאפס היא כנראה לא הדרך. פרויקט scraping כזה הוא התחייבות. הוא דורש מומחיות לא רק בכתיבת הקוד הראשוני, אלא גם בהבנת מערכות הגנה, ניהול תשתיות, וניטור מתמיד. תעשו הערכה כנה של המשאבים והיכולות שלכם לפני שאתם צוללים פנימה.
