פיתוח בוט לניתוח מוצרים חדשים מתחיל בניתוח מבנה הקטלוג של הספק. ניתוח דפי אינטרנט מאפשר לבצע איסוף נתונים אוטומטי. אנו בוחרים באסטרטגיית זיהוי דלתא אופטימלית: לפי תאריך הוספה, לפי מדור 'מוצרים חדשים', או לפי השוואת רשימת מק"טים. השיטה האחרונה היא אוניברסלית ואינה תלויה במבנה הדף. היא מאפשרת למצוא מוצרים חדשים גם אם הספק אינו מדגיש מוצרים חדשים ויזואלית.
הבוט חוסך עד 80% מזמן הצוות בניטור. במקום לגלוש בעשרות דפים מדי יום, מקבלים הודעה עם רשימת מק"טים חדשים. המחיר של טעויות ניטור ידני גבוה—מוצר חם שהוחמץ או התחלה מאוחרת במכירות. אוטומציה פותרת בעיה זו.
כיצד פועל זיהוי מוצרים חדשים לפי תאריך
אם לכרטיס מוצר יש תאריך הוספה, אנו מנתחים את דפי הקטלוג עד שנתקלים ברישומים ישנים יותר מהתמונת מצב האחרונה. זה חוסך תעבורה וזמן. דוגמת יישום ב-PHP:
// app/Services/NewArrivals/DateBasedDetector.php
class DateBasedDetector {
public function detectNew(string $categoryUrl, \DateTimeInterface $since): array {
$page = 1;
$newProducts = [];
do {
$items = $this->scrapePage($categoryUrl, $page);
$hasOlderItems = false;
foreach ($items as $item) {
$itemDate = $this->parseDate($item['date_added'] ?? '');
if ($itemDate && $itemDate < $since) {
$hasOlderItems = true;
break;
}
if (!$this->existsInDatabase($item['sku'])) {
$newProducts[] = $item;
}
}
$page++;
} while (!$hasOlderItems && count($items) > 0);
return $newProducts;
}
}שיטה זו עובדת היטב כאשר הספק מציין תאריכים בבירור. אם התאריכים חסרים, אנו משתמשים באסטרטגיות אחרות.
אילו אסטרטגיות זיהוי מוצרים חדשים קיימות?
נשווה בין שלוש גישות עיקריות:
| אסטרטגיה | דיוק | תלות במבנה | מתי להשתמש |
|---|---|---|---|
| לפי תאריך הוספה | גבוה | בינוני—נדרש תאריך בדף | אם הספק מספק תאריכים באופן עקבי |
| לפי מדור 'מוצרים חדשים' | בינוני | נמוך—מספיק כתובת המדור | אם קיים דף נפרד למוצרים חדשים |
| לפי השוואת מק"טים | גבוה | נמוך—נדרשת רק רשימת מק"טים | שיטה אוניברסלית, בלתי תלויה במבנה הדף |
שיטת השוואת המק"טים מדויקת פי 2–3 יותר מכיוון שאינה מסתמכת על מטא-דאטה של הדף. היישום שלה:
// app/Services/NewArrivals/SkuDiffDetector.php
class SkuDiffDetector
{
public function detect(int $supplierId, array $currentSkus): array
{
$previousSnapshot = SupplierSnapshot::where('supplier_id', $supplierId)
->latest()
->first();
if (!$previousSnapshot) {
$this->saveSnapshot($supplierId, $currentSkus);
return [];
}
$previousSkus = $previousSnapshot->sku_list;
$newSkus = array_diff($currentSkus, $previousSkus);
$removedSkus = array_diff($previousSkus, $currentSkus);
$this->saveSnapshot($supplierId, $currentSkus);
if (!empty($removedSkus)) {
Log::info("Supplier #{$supplierId}: removed SKUs", ['skus' => $removedSkus]);
SupplierProductsRemoved::dispatch($supplierId, $removedSkus);
}
return $newSkus;
}
private function saveSnapshot(int $supplierId, array $skus): void
{
SupplierSnapshot::create([
'supplier_id' => $supplierId,
'sku_list' => $skus,
'sku_count' => count($skus),
'captured_at' => now(),
]);
}
}כאן, תמונות מצב של מק"טים נשמרות במסד הנתונים, וישנות נמחקות אוטומטית לאחר 90 יום כדי לא להעמיס על האחסון.
מחזור זיהוי ועיבוד מלא
נאגד הכל לתוך Job אחד שפועל לפי לוח זמנים:
// app/Jobs/CheckSupplierNewArrivals.php
class CheckSupplierNewArrivals implements ShouldQueue
{
public int $tries = 3;
public int $timeout = 600;
public function handle(
SupplierScraper $scraper,
SkuDiffDetector $detector,
NewArrivalsNotifier $notifier
): void {
$supplier = Supplier::findOrFail($this->supplierId);
$allProducts = $scraper->scrapeAllProductSkus($supplier);
$currentSkus = array_column($allProducts, 'sku');
$newSkus = $detector->detect($this->supplierId, $currentSkus);
if (empty($newSkus)) {
Log::info("No new arrivals for supplier #{$this->supplierId}");
return;
}
$newProducts = array_filter(
$allProducts,
fn($p) => in_array($p['sku'], $newSkus)
);
$notifier->notify($supplier, $newProducts);
if ($supplier->auto_import_new_arrivals) {
foreach ($newProducts as $product) {
ImportNewSupplierProduct::dispatch($this->supplierId, $product)
->onQueue('imports');
}
} else {
foreach ($newProducts as $product) {
PendingImport::create([
'supplier_id' => $this->supplierId,
'data' => $product,
'status' => 'pending_review',
]);
}
}
Log::info("Found new arrivals", [
'supplier_id' => $this->supplierId,
'count' => count($newProducts),
]);
}
}ה-Job רץ בתור, תומך בעד 3 ניסיונות חוזרים, ויש לו זמן קצוב של 10 דקות, המספיק לקטלוגים של עד 10,000 מק"טים.
הודעות ואינטגרציות
ניתן לקבל עדכון מיידי על מוצרים חדשים שנמצאו. אנו תומכים בדוא"ל, Slack, Telegram ו-webhooks. דוגמת הודעה בדוא"ל ו-Slack:
// app/Notifications/NewSupplierArrivalsNotification.php
class NewSupplierArrivalsNotification extends Notification implements ShouldQueue
{
use Queueable;
public function via($notifiable): array
{
return ['mail', 'slack'];
}
public function toMail($notifiable): MailMessage
{
return (new MailMessage)
->subject("Новые поступления: {$this->supplier->name} ({$this->count} товаров)")
->line("Обнаружено {$this->count} новых товаров у поставщика **{$this->supplier->name}**")
->line("Дата обнаружения: " . now()->format('d.m.Y H:i'))
->action('Просмотреть новинки', route('admin.pending-imports.index', [
'supplier_id' => $this->supplier->id,
]))
->line('Товары ожидают проверки перед публикацией.');
}
public function toSlack($notifiable): SlackMessage
{
return (new SlackMessage)
->content(
"🆕 *{$this->supplier->name}*: {$this->count} новых товаров\n" .
implode("\n", array_map(
fn($p) => "• {$p['sku']} — {$p['name']}",
array_slice($this->products, 0, 10)
))
);
}
}ההודעות כוללות את 10 המוצרים הראשונים; הרשימה המלאה זמינה בלוח הניהול.
תור בדיקה ידנית
מוצרים חדשים דורשים לעיתים קרובות בדיקה ידנית: קטגוריה, תיאור SEO, תמונות. לשם כך, אנו יוצרים ממשק מיתון עם פונקציונליות אישור או דחייה:
// app/Http/Controllers/Admin/PendingImportController.php
class PendingImportController extends Controller
{
public function index(Request $request): Response
{
$pending = PendingImport::query()
->with('supplier')
->when($request->supplier_id, fn($q, $id) => $q->where('supplier_id', $id))
->where('status', 'pending_review')
->orderBy('created_at', 'desc')
->paginate(50);
return Inertia::render('Admin/PendingImports/Index', [
'imports' => $pending,
]);
}
public function approve(PendingImport $import): RedirectResponse
{
ImportNewSupplierProduct::dispatch($import->supplier_id, $import->data);
$import->update(['status' => 'approved']);
return back()->with('success', 'Товар отправлен в импорт');
}
public function reject(PendingImport $import, Request $request): RedirectResponse
{
$import->update([
'status' => 'rejected',
'reject_reason' => $request->reason,
]);
return back()->with('success', 'Товар отклонён');
}
}המודרטור רואה את כל המוצרים החדשים ברשימה אחת ויכול לסקור במהירות ולשלוח מוצרים לחנות.
מה כולל פיתוח בוט הניתוח?
היקף העבודה כולל:
- ניתוח קטלוגים של ספקים ובחירת אסטרטגיית הזיהוי האופטימלית.
- פיתוח מודול איסוף מק"טים (תמיכה באימות, דפדוף, CAPTCHA).
- יישום זיהוי דלתא עם אחסון תמונות מצב.
- הגדרת הודעות (דוא"ל, Slack, Telegram, webhooks).
- פיתוח תור בדיקה ידנית עם ממשק מיתון.
- יצירת תיעוד תפעולי.
- בדיקות על נתוני ספק אמיתיים.
- הדרכת צוות על המערכת.
לוחות זמנים ועלות
פיתוח גלאי לספק אחד עם הודעות ותור אורך בין 4 ל-6 ימי עבודה. העלות מחושבת באופן אישי—תלויה במורכבות הקטלוג, מספר הספקים והאינטגרציות הנדרשות. אנו מבטיחים פעילות יציבה של הבוט ומספקים תיעוד תפעולי.
למה להזמין פיתוח מאיתנו?
למהנדסים שלנו יש ניסיון של למעלה מ-5 שנים בניתוח קטלוגים מורכבים. בתקופה זו, יישמנו למעלה מ-50 פרויקטים עבור חנויות מקוונות ומרקטפלייסים. אנו מבטיחים עמידה בלוחות זמנים, תמיכה לאחר השקה וסיוע בהתקנה. נבחן את הפרויקט שלך ונציע את הפתרון האופטימלי. צרו קשר לייעוץ.
כיצד הבוט מתמודד עם שגיאות ניתוח?
לטיפול בשגיאות, אנו משתמשים בניסיונות חוזרים עם השהיה אקספוננציאלית. אם דף לא נטען, הבוט ממתין 30 שניות ומנסה שוב. לאחר שלושה כישלונות, נשלחת הודעה למנהל. מתנהל גם יומן שגיאות עם כתובת URL וקוד תגובה מפורט.| שלב | משך |
|---|---|
| ניתוח ועיצוב | 1–2 ימים |
| פיתוח הגלאי | 1–2 ימים |
| אינטגרציית הודעות ותור | יום אחד |
| בדיקות וניפוי שגיאות | יום אחד |
| תיעוד והדרכה | 0.5 ימים |
בוט הניתוח מחזיר את ההשקעה תוך 2–3 חודשים בזכות חיסכון בזמן למנהלים והפחתת מכירות שהוחמצו. קבלו ייעוץ על הפרויקט שלכם—נחשב את העלות ולוחות הזמנים.







