כיצד בוט עוזר לך לעקוב אחר מוצרים חדשים של מתחרים: הגדרה ותוצאות
גלישה ידנית בקטלוגים של מתחרים גוזלת שעות רבות מדי יום. במקום להתמקד באסטרטגיה, אתה פותח עשרות עמודים בחיפוש אחר פריטים חדשים. מתחרה אחד עם 20 קטגוריות ו-50 עמודי קטלוג לוקח כ-30–40 דקות ביום. עם 5–10 מתחרים, זה הופך למשמרת עבודה מלאה, וטעויות אנוש מובילות בהכרח להחמצה של 20–30% מהמוצרים החדשים.
אנחנו הופכים תהליך זה לאוטומטי. הבוט שלנו מבצע ניטור מתחרים אוטומטי, מעקב אחר מוצרים חדשים וגרידת קטלוג SKU. הוא סורק עמודי מוצר מדי יום לפי לוח זמנים ומודיע לך מיד על פריטים חדשים דרך טלגרם. אתה מקבל רק שינויים אמיתיים, ללא רעש. זה מאפשר לך להגיב מהר יותר מהמתחרים ולא לאבד קהל.
עם ניסיון של למעלה מ-5 שנים, פיתחנו פתרונות ל-40+ חנויות מקוונות, החל מפרויקטים נישתיים קטנים ועד מרקטפלייסים גדולים. המומחיות שלנו מבטיחה פעולה יציבה גם כשהפריסה של המתחרים משתנה—אנו משתמשים בסלקטורים סמנטיים ואסטרטגיות גיבוי. חיסכון בזמן בניטור: עד 80%. הבוט מעבד עד 10,000 SKU ביום, ומייצר דוחות בזמן אמת.
מדוע ניטור ידני אינו יעיל?
למתחרים יש מאות עמודי קטלוג שמתעדכנים מדי יום. סקירה ידנית שלהם מבזבזת זמן ומחמיצה פריטים חדשים. הבוט בודק כל עמוד לפי לוח זמנים, ואתה לומד על מוצרים חדשים תוך דקות.
יתר על כן, העין האנושית אינה יכולה לעקוב אחר עשרות קטגוריות בו זמנית. החמצות הן בלתי נמנעות, במיוחד אם מוצר מופיע באמצע רשימה. הבוט לוכד כל שינוי על ידי השוואת המצב הנוכחי עם תמונת בסיס.
כיצד הבוט מזהה מוצרים חדשים?
ניטור מוצרים חדשים שונה מניטור מחירים. אנו עוקבים לא אחר כתובת URL ספציפית אלא אחר קטעי קטלוג—קטגוריות, עמודי "חדש", תוצאות חיפוש. האלגוריתם פועל כך:
Конфигурация (URL каталога + селектор) → Scraper → Snapshot → Diff → Alert - הסורק טוען את העמוד ומחלץ את רשימת המוצרים באמצעות סלקטורי CSS.
- כל מוצר נשמר במסד הנתונים עם hash של שדה.
- בסריקות הבאות, הרשימה החדשה מושווה לקודמת.
- עמדות שחסרות בתמונת המצב הישנה מסומנות כחדשות.
- המערכת שולחת הודעה לטלגרם.
אלגוריתם פעולה מפורט של הגלאי
עבור כל מתחרה, מוגדר קובץ JSON עם סלקטורים וכללי פגינציה:
{
"pagination": {
"type": "url_param",
"param": "page",
"max_pages": 20
},
"item_selector": ".catalog-item",
"fields": {
"url": {
"selector": "a.product-link",
"attr": "href"
},
"title": {
"selector": ".product-name",
"text": true
},
"sku": {
"selector": "[data-sku]",
"attr": "data-sku"
},
"price": {
"selector": ".price",
"text": true
},
"image": {
"selector": "img.product-image",
"attr": "src"
}
}
}סכמת נתונים לאחסון תמונות מצב ופריטים חדשים:
CREATE TABLE competitor_catalogs (
id BIGSERIAL PRIMARY KEY,
competitor_id INT REFERENCES competitors(id),
url TEXT NOT NULL,
scrape_config JSONB NOT NULL,
check_interval INTERVAL DEFAULT '6 hours',
last_checked_at TIMESTAMP,
is_active BOOLEAN DEFAULT TRUE
);
CREATE TABLE competitor_items (
id BIGSERIAL PRIMARY KEY,
catalog_id BIGINT REFERENCES competitor_catalogs(id),
external_url TEXT NOT NULL,
title TEXT,
external_sku VARCHAR(255),
price NUMERIC(12,2),
image_url TEXT,
first_seen_at TIMESTAMP DEFAULT NOW(),
last_seen_at TIMESTAMP DEFAULT NOW(),
is_new BOOLEAN DEFAULT TRUE,
UNIQUE(catalog_id, external_url)
);
CREATE INDEX idx_competitor_items_new ON competitor_items(catalog_id, first_seen_at) WHERE is_new = TRUE;הסורק עצמו מיושם ב-PHP באמצעות Symfony DomCrawler:
class CatalogScraper {
public function scrape(CompetitorCatalog $catalog): array {
$config = $catalog->scrape_config;
$items = [];
$maxPages = $config['pagination']['max_pages'] ?? 1;
for ($page = 1; $page <= $maxPages; $page++) {
$url = $this->buildPageUrl($catalog->url, $config['pagination'], $page);
$html = $this->fetchWithRetry($url);
if (!$html) break;
$pageItems = $this->extractItems($html, $config);
if (empty($pageItems)) break;
$items = array_merge($items, $pageItems);
usleep(rand(1_500_000, 3_000_000));
}
return $items;
}
private function extractItems(string $html, array $config): array {
$crawler = new \Symfony\Component\DomCrawler\Crawler($html);
$items = [];
$crawler->filter($config['item_selector'])->each(function ($node) use ($config, &$items) {
$item = [];
foreach ($config['fields'] as $field => $fieldConfig) {
try {
$el = $node->filter($fieldConfig['selector'])->first();
if ($el->count() === 0) continue;
$item[$field] = isset($fieldConfig['attr']) ? $el->attr($fieldConfig['attr']) : $el->text();
} catch (\Exception $e) {
continue;
}
}
if (!empty($item['url'])) {
$items[] = $item;
}
});
return $items;
}
}שירות זיהוי מוצרים חדשים:
class NewProductDetectionService {
public function process(CompetitorCatalog $catalog): DetectionResult {
$scraped = $this->scraper->scrape($catalog);
$newItems = [];
foreach ($scraped as $item) {
$url = $this->normalizeUrl($item['url'], $catalog->url);
$existing = CompetitorItem::where([
'catalog_id' => $catalog->id,
'external_url' => $url,
])->first();
if (!$existing) {
$created = CompetitorItem::create([
'catalog_id' => $catalog->id,
'external_url' => $url,
'title' => $item['title'] ?? null,
'external_sku' => $item['sku'] ?? null,
'price' => $this->parsePrice($item['price'] ?? ''),
'image_url' => $item['image'] ?? null,
'is_new' => true,
]);
$newItems[] = $created;
} else {
$existing->update(['last_seen_at' => now()]);
}
}
$disappeared = CompetitorItem::where('catalog_id', $catalog->id)
->where('last_seen_at', '<', now()->subDays(3))
->get();
$catalog->update(['last_checked_at' => now()]);
return new DetectionResult(newItems: $newItems, disappeared: $disappeared);
}
}לאחר זיהוי פריטים חדשים, הבוט שולח הודעת טלגרם עם מידע קצר: שם, מחיר, קישור. ההודעות מגיעות תוך דקה מהסריקה.
עקיפת הגנות בוט
| הגנה | שיטת עקיפה |
|---|---|
| Cloudflare Bot Management | Playwright + תוסף stealth |
| הגבלת קצב | השהיות אקראיות של 2–5 שניות בין בקשות |
| חסימות IP | רוטציית פרוקסי (פרוקסי מגורים) |
| דרישת Cookie/סשן | דפדפן headless עם שמירת סשן |
| עיבוד JS | Playwright/Puppeteer במקום curl |
מה כלול בעבודה
- הגדרה לעד 5 מתחרים (קטגוריות, סלקטורים, מרווחים)
- הגדרת הודעות טלגרם (פריטים חדשים, היעלמויות)
- פריסה על השרת שלך (תמונת Docker)
- תיעוד תפעולי
- הדרכת צוות (שעה אחת)
- תמיכה ושינויים למשך חודש אחד
- המחיר מתחיל מ-$500
השוואת גישות
| פרמטר | ניטור ידני | בוט |
|---|---|---|
| זמן לבדיקת מתחרה אחד | 30 דקות/יום | שנייה אחת/יום |
| פריטים חדשים שהוחמצו | עד 30% | <1% |
| תגובה לשינויים | שעות–ימים | דקות |
| עלות הרחבה | לינארית | קבועה |
| עלות | שעות משתנות | קבועה מ-$500 |
טעויות ניטור אופייניות וכיצד להימנע מהן
- התעלמות מפגינציה. אם למתחרה יש יותר מעמוד אחד, הבוט יעבור על כולם. בדוק את הגדרת
Конфигурация (URL каталога + селектор) → Scraper → Snapshot → Diff → Alert. - בקשות תכופות מדי. סיכון לחסימה. אנו ממליצים על מרווחים של 6–12 שעות.
- סלקטורים נוקשים. כשהפריסה משתנה, הסלקטורים עלולים להישבר. השתמש בתכונות data או במחלקות מזהות.
- חוסר בטיפול בשגיאות. אם עמוד אינו זמין זמנית, הבוט צריך לנסות שוב עם השהיה.
לוח זמנים ליישום
- CatalogScraper + הגדרת JSON: 1–2 ימים
- NewProductDetectionService + סכמת נתונים: יום אחד
- הודעות טלגרם: 0.5 יום
- מתאם Playwright לאתרי JS: +יום אחד
- רוטציית פרוקסי: +0.5 יום
סה"כ: 3–4 ימי עבודה.
קבל ייעוץ על אוטומציה של ניטור. המהנדסים שלנו יבדקו את המתחרים שלך ויציעו את הפתרון האופטימלי.
צור קשר כדי לדון במשימה שלך. נעריך את הפרויקט ונבחר תצורה שמתאימה לתקציב שלך.







