למה `requests` פשוט לא יספיק ל-Urbanica

בואו נניח את זה על השולחן מההתחלה. אם תנסו לשלוח בקשת GET פשוטה לכתובת מוצר ב-Urbanica, תקבלו חזרה מעטפת HTML כמעט ריקה. כל התוכן העשיר — שם המוצר, תמונות, מחירים, מידות זמינות — נטען דינמית באמצעות JavaScript לאחר שהדף הראשוני כבר בדפדפן. זו התנהגות קלאסית של Single Page Application (SPA), כנראה מבוססת React או Vue.

המשמעות היא שכל כלי שמבוסס על ניתוח HTML סטטי פשוט לא רלוונטי כאן. אתם מבזבזים את הזמן. הפתרון הוא להשתמש ב-headless browser. ושלא יהיה ספק, ב-2025 הבחירה הברורה היא Playwright. הוא מהיר יותר, יציב יותר וה-API שלו נקי ואינטואיטיבי בהרבה מזה של Selenium. היכולת שלו ליירט בקשות רשת היא קריטית כאן. במקום לחכות שהדף כולו יסיים להיטען, אפשר להאזין לבקשות ה-XHR/Fetch שהדפדפן שולח, לזהות את ה-API endpoint שמחזיר את נתוני המוצר, ולפעמים אפילו לחלץ את המידע ישירות מה-JSON שה-API מחזיר. זה יכול לקצץ את זמן הריצה פר דף ב-50-70% בהשוואה להמתנה מלאה ל-DOM.

איסוף קטלוג מלא: מעקב אחרי קטגוריות ומוצרים

המשימה הראשונה והבסיסית ביותר היא איסוף קטלוג Urbanica המלא. זה הבסיס לכל ניתוח עתידי. התהליך מתחיל בדרך כלל מניתוח מבנה הניווט של האתר. צריך למפות את כל הקטגוריות ותתי-הקטגוריות כדי לבנות את עץ האתר. משם, נכנסים לכל עמוד קטגוריה ומתמודדים עם פג'ינציה. באתרים כמו Urbanica, זו לרוב גלילה אינסופית (infinite scroll), שמפעילה בקשת API נוספת כדי לטעון את סט המוצרים הבא. תצטרכו לדמות גלילה עם Playwright עד שלא יופיעו יותר מוצרים חדשים.

במהלך סריקת הקטלוג, חשוב לאסוף לא רק את הקישור למוצר, אלא גם נתונים בסיסיים כמו שמות מוצרים וקטגוריות ישירות מעמוד הרשימה. זה חוסך בקשות מיותרות בהמשך. קטלוג של אתר אופנה בסדר גודל כזה יכול להכיל בקלות 5,000-15,000 מוצרים שונים (SKUs). סריקה מלאה שלו דורשת אלפי בקשות, וזה בדיוק המקום שבו אסטרטגיית ניהול פרוקסי חכמה הופכת להיות קריטית. בלי רוטציה נכונה של כתובות IP, אתם תתחילו לראות שגיאות 403 או דפי CAPTCHA מהר מאוד.

מעבר לקטלוג: ניטור מחירים ומלאי בזמן אמת

כאן נמצא הערך האמיתי עבור רוב מקרי השימוש. ניטור מחירים ב-Urbanica ומעקב מלאי/זמינות הם לא תהליכים חד-פעמיים. הם דורשים סריקות תכופות, לפעמים כל שעה, כדי לתפוס שינויים דינמיים, מבצעי בזק או עדכוני מלאי. הרצת scraper מלא עם Playwright כל שעה היא לא יעילה וצורכת משאבים רבים. הגישה המקצועית היא לבצע reverse engineering לבקשות ה-API של האתר.

פתחו את כלי המפתחים בדפדפן, נווטו לעמוד מוצר וסננו את בקשות הרשת לפי XHR/Fetch. מהר מאוד תזהו בקשה שמחזירה JSON עם כל המידע שאתם צריכים: מחיר, מחיר מבצע, וחשוב מכל — מערך או אובייקט שמפרט את המלאי לפי מידה וצבע. ברגע שיש לכם את ה-endpoint, ה-headers הנדרשים (כמו Authorization או טוקנים אחרים) וה-payload, אתם יכולים לפנות ל-API הזה ישירות עם כלי כמו httpx ב-Python. זה מהיר פי 10-20 מרינדור דף שלם. אבל יש פה מלכודת: ה-API הזה הוא פנימי ולא מתועד. הוא יכול להשתנות ללא אזהרה. בוקר אחד ה-scraper שלכם יתחיל להיכשל כי מפתח בצד של Urbanica שינה שם של שדה ב-JSON. לכן, חובה לבנות מערכת ניטור ובדיקות שמזהה שינויים כאלה באופן אוטומטי.

תרחיש הכשל הנפוץ ביותר באתרי אופנה

בואו נדבר על ה-failure mode שראיתי הכי הרבה בפרויקטים של scraping באתרי אופנה כמו Urbanica. זה לא חסימת IP פשוטה, זה משהו מתוחכם יותר. ה-scraper רץ במשך שבועות, נראה שהכל תקין, אחוזי ההצלחה גבוהים, ואז מישהו בצוות הדאטה שם לב שהנתונים לא הגיוניים. המחירים נראים נכונים, אבל מלאי המוצרים קפוא. אותן מידות זמינות לכל המוצרים, כל הזמן.

מה שקרה הוא שהאתר זיהה את ה-scraper שלכם והתחיל להגיש לו דפים מתוך cache ישן. הוא לא חוסם אתכם לגמרי, אלא נותן לכם מידע לא רלוונטי. זה קורה כי ה-fingerprint של הדפדפן האוטומטי שלכם (אפילו עם Playwright) חשוד. הוא חסר מאפיינים של דפדפן אנושי אמיתי, והמערכות בצד השרת מסיטות אתכם בשקט לגרסה סטטית של האתר. הפתרון היחיד פה הוא להשקיע ב-stealth. זה אומר שימוש בגרסאות מיוחדות של כלי האוטומציה כמו Playwright-stealth למניעת זיהוי, ניהול קוקיז ו-sessions בצורה שמדמה משתמש אמיתי, ורוטציה לא רק של IP אלא גם של User-Agent ו-headers אחרים. אם אתם לא מטפלים ב-fingerprinting, אתם אוספים זבל בלי לדעת.

ממודיעין מתחרים ועד ליצירת API מותאם

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

מעבר לניתוח פנימי, הדרישה הנפוצה ביותר מלקוחות היא לקבל את הנתונים בפורמט נגיש. אף אחד לא רוצה להתעסק עם קבצי JSON גולמיים. השלב הסופי בכל פרויקט scraping רציני הוא בניית שכבת פלט. זה יכול להיות API / קובץ נתונים Urbanica שאתם מספקים. לרוב, מדובר בייצוא יומי או שבועי של כל הקטלוג והמלאי לקובץ CSV או Parquet שמועלה ל-S3, או בניית API פנימי פשוט (למשל עם FastAPI) שמאפשר לצוותים אחרים לתשאל את הנתונים שאספתם. המטרה היא להפוך את המידע הגולמי למוצר נתונים שמיש, שכל אחד בארגון יכול לצרוך בקלות. אם אתם נתקלים בחסימות מתקדמות יותר, כמו אלו של Cloudflare, כדאי לקרוא על טכניקות מתקדמות לעקיפת הגנות.