מנתח ביקורות: אוטומציה של איסוף וייבוא מפלטפורמות מסחר

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

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
מנתח ביקורות: אוטומציה של איסוף וייבוא מפלטפורמות מסחר
בינוני
~3-5 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

איסוף וייבוא ביקורות מפלטפורמות מסחר: פיתוח פארסר

אנו בונים פארסרים לאיסוף אוטומטי של ביקורות מפלטפורמות מסחר. לקוח איבד 30% מהמרות בגלל ביקורות מיושנות — איסוף ידני לקח שעות, והנתונים לא עודכנו במשך שבועות. הצוות שלנו (ניסיון של 5+ שנים, 50+ פרויקטים) יצר פתרון שאוסף ביקורות מ-Wildberries, Ozon, Yandex.Market ופלטפורמות אחרות, מנרמל אותן ומייבא אותן למסד הנתונים של החנות שלך. חיסכון בזמן — עד 70%. החזר השקעה — 2–3 חודשים. הזמינו פיתוח פארסר לחנות המקוונת שלכם.

תרחיש טיפוסי: מנהל מעתיק ידנית ביקורות מ-5 פלטפורמות מסחר עבור 200 מוצרים — זה 8 שעות ביום. הנתונים מתיישנים, לקוחות לא רואים ביקורות חדשות במשך שבועות, והאמון יורד. פארסר אוסף ביקורות כל שעתיים, ומעדכן דפי מוצר בזמן אמת. תוצאה: גידול בהמרות של 15% בחודש הראשון.

מבחינה טכנית, כל פלטפורמת מסחר היא אתגר בפני עצמו. Wildberries מציעה JSON API, אבל עם מגבלה של 1000 ביקורות לכל סשן. Ozon היא SPA על Nuxt, שבו נתונים נטענים דרך GraphQL — אנחנו צריכים לחקות דפדפן עם Playwright. Yandex.Market משנה את המבנה שלו כל חצי שנה, אז אנחנו משתמשים בפארסינג אדפטיבי עם אסטרטגיית גיבוי. המחסנית שלנו: Python לפלטפורמות בעומס גבוה, PHP (Laravel) לאינטגרציה עם האתר שלך.

פלטפורמות נתמכות ושיטות

פלטפורמה שיטה הערות
Wildberries JSON API API פתוח, פגינציה, עד 1000 ביקורות לכל סשן
Ozon Playwright SPA, דורש הרשאה, איטי פי 50 מ-JSON
Yandex.Market API לא רשמי הגבלת קצב, דורש סיבוב פרוקסי
Google Reviews Places API בתשלום, רשמי, עד 5 ביקורות לכל בקשה (דורש מנוי עסקי)
Otzovik.com פארסינג HTML CAPTCHA בבקשות המוניות — אנו משתמשים בפותרי CAPTCHA
iHerb HTML / JSON API HTML מובנה, הקל ביותר

השוואת שיטות: JSON-API (Wildberries) מעבד 1000 ביקורות ב-10 שניות, בעוד Selenium על Ozon לוקח 5 דקות לאותן 1000. זה הבדל של פי 30. לביצועים, אנו בוחרים ב-JSON בכל מקום אפשרי.

איך הפארסר של Wildberries עובד

אנו משתמשים ב-httpx אסינכרוני כדי לעבור על פגינציה. דוגמה:

לחצו להרחבת דוגמת קוד Python
# scraper/reviews/wildberries.py
import httpx
import asyncio
from dataclasses import dataclass
from typing import Optional

@dataclass
class Review:
    external_id: str
    product_nm_id: int
    author: str
    rating: int
    text: str
    pros: Optional[str]
    cons: Optional[str]
    date: str
    photos: list[str]
    helpful_count: int

class WildberriesReviewScraper:
    REVIEWS_URL = "https://feedbacks2.wb.ru/feedbacks/v2/{nm_id}"

    def __init__(self):
        self.client = httpx.AsyncClient(
            headers={
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
                "Origin": "https://www.wildberries.ru",
                "Referer": "https://www.wildberries.ru/",
            }
        )

    async def get_reviews(self, nm_id: int, take: int = 100) -> list[Review]:
        all_reviews = []
        skip = 0
        while True:
            url = self.REVIEWS_URL.format(nm_id=nm_id)
            params = {
                "immt": nm_id,
                "skip": skip,
                "take": take,
                "order": "dateDesc",
            }
            resp = await self.client.get(url, params=params)
            resp.raise_for_status()
            data = resp.json()
            feedbacks = data.get("feedbacks", [])
            if not feedbacks:
                break
            for fb in feedbacks:
                all_reviews.append(self._normalize(nm_id, fb))
            skip += take
            await asyncio.sleep(1.0)  # Ограничение: не более 1000 отзывов за сессию
            if skip >= 1000:
                break
        return all_reviews

    def _normalize(self, nm_id: int, raw: dict) -> Review:
        photos = []
        for photo in raw.get("photos", []):
            if full_url := photo.get("fullSize"):
                photos.append(full_url)
        return Review(
            external_id=raw.get("id", ""),
            product_nm_id=nm_id,
            author=raw.get("wbUserDetails", {}).get("name", "Покупатель"),
            rating=raw.get("productValuation", 0),
            text=raw.get("text", ""),
            pros=raw.get("pros"),
            cons=raw.get("cons"),
            date=raw.get("createdDate", ""),
            photos=photos,
            helpful_count=raw.get("feedbackValuation", 0),
        )
"}

פארסינג של ביקורות HTML

לאתרים ללא API, אנו מפרסים HTML באמצעות PHP ו-Symfony Crawler. דוגמה עבור iHerb:

// app/Services/ReviewScraper/HtmlReviewScraper.php
class HtmlReviewScraper
{
    public function scrapeIherb(string $productUrl, int $pages = 5): array
    {
        $reviews = [];
        for ($page = 1; $page <= $pages; $page++) {
            $html = $this->fetch("{$productUrl}?p={$page}&is=1&s=6");
            $crawler = new Crawler($html);
            $items = $crawler->filter('[itemprop="review"]');
            if (!$items->count()) break;
            $items->each(function (Crawler $node) use (&$reviews) {
                $reviews[] = [
                    'external_id' => $node->attr('data-review-id'),
                    'author' => trim($node->filter('[itemprop="author"]')->text('')),
                    'rating' => (int) $node->filter('[itemprop="ratingValue"]')->attr('content'),
                    'date' => $node->filter('[itemprop="datePublished"]')->attr('content'),
                    'title' => trim($node->filter('[itemprop="name"]')->text('')),
                    'text' => trim($node->filter('[itemprop="reviewBody"]')->text('')),
                    'helpful' => (int) $node->filter('.helpful-yes')->text('0'),
                    'verified' => $node->filter('.verified-buyer')->count() > 0,
                ];
            });
            sleep(rand(2, 4));
        }
        return $reviews;
    }
}

הסרת כפילויות וייבוא ל-Laravel

לאחר האיסוף, ביקורות עוברות דרך Job עם הסרת כפילויות לפי # scraper/reviews/wildberries.py import httpx import asyncio from dataclasses import dataclass from typing import Optional @dataclass class Review: external_id: str product_nm_id: int author: str rating: int text: str pros: Optional[str] cons: Optional[str] date: str photos: list[str] helpful_count: int class WildberriesReviewScraper: REVIEWS_URL = "https://feedbacks2.wb.ru/feedbacks/v2/{nm_id}" def __init__(self): self.client = httpx.AsyncClient( headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Origin": "https://www.wildberries.ru", "Referer": "https://www.wildberries.ru/", } ) async def get_reviews(self, nm_id: int, take: int = 100) -> list[Review]: all_reviews = [] skip = 0 while True: url = self.REVIEWS_URL.format(nm_id=nm_id) params = { "immt": nm_id, "skip": skip, "take": take, "order": "dateDesc", } resp = await self.client.get(url, params=params) resp.raise_for_status() data = resp.json() feedbacks = data.get("feedbacks", []) if not feedbacks: break for fb in feedbacks: all_reviews.append(self._normalize(nm_id, fb)) skip += take await asyncio.sleep(1.0) # Ограничение: не более 1000 отзывов за сессию if skip >= 1000: break return all_reviews def _normalize(self, nm_id: int, raw: dict) -> Review: photos = [] for photo in raw.get("photos", []): if full_url := photo.get("fullSize"): photos.append(full_url) return Review( external_id=raw.get("id", ""), product_nm_id=nm_id, author=raw.get("wbUserDetails", {}).get("name", "Покупатель"), rating=raw.get("productValuation", 0), text=raw.get("text", ""), pros=raw.get("pros"), cons=raw.get("cons"), date=raw.get("createdDate", ""), photos=photos, helpful_count=raw.get("feedbackValuation", 0), ) ו-// app/Services/ReviewScraper/HtmlReviewScraper.php class HtmlReviewScraper { public function scrapeIherb(string $productUrl, int $pages = 5): array { $reviews = []; for ($page = 1; $page <= $pages; $page++) { $html = $this->fetch("{$productUrl}?p={$page}&is=1&s=6"); $crawler = new Crawler($html); $items = $crawler->filter('[itemprop="review"]'); if (!$items->count()) break; $items->each(function (Crawler $node) use (&$reviews) { $reviews[] = [ 'external_id' => $node->attr('data-review-id'), 'author' => trim($node->filter('[itemprop="author"]')->text('')), 'rating' => (int) $node->filter('[itemprop="ratingValue"]')->attr('content'), 'date' => $node->filter('[itemprop="datePublished"]')->attr('content'), 'title' => trim($node->filter('[itemprop="name"]')->text('')), 'text' => trim($node->filter('[itemprop="reviewBody"]')->text('')), 'helpful' => (int) $node->filter('.helpful-yes')->text('0'), 'verified' => $node->filter('.verified-buyer')->count() > 0, ]; }); sleep(rand(2, 4)); } return $reviews; } } . דוגמה:

// app/Jobs/ImportProductReviews.php
class ImportProductReviews implements ShouldQueue {
    public int $tries = 3;
    public int $backoff = 120;

    public function handle(ReviewImportService $service): void {
        $mapping = ProductReviewMapping::where('product_id', $this->productId)
            ->where('source', $this->source)
            ->firstOrFail();

        $reviews = $this->scrape($mapping->external_id);
        $imported = 0;
        $skipped = 0;

        foreach ($reviews as $reviewData) {
            $exists = ProductReview::where([
                'source' => $this->source,
                'external_id' => $reviewData['external_id'],
            ])->exists();

            if ($exists) {
                $skipped++;
                continue;
            }

            $service->import($this->productId, $this->source, $reviewData);
            $imported++;
        }

        Log::info("Reviews imported", [
            'product_id' => $this->productId,
            'source' => $this->source,
            'imported' => $imported,
            'skipped' => $skipped,
        ]);
    }
}

סינון ומודרציה

מילות עצירה (ספאם, פרסומות, ניבולי פה), ביקורות קצרות מדי (<20 תווים), ואנונימיזציה של מחברים — הכל ניתן להתאמה אישית. להלן דוגמת שירות:

// app/Services/ReviewImportService.php
class ReviewImportService
{
    private array $stopWords = ['купите', 'скидка', 'промокод', 'vk.com', 't.me'];

    public function import(int $productId, string $source, array $data): ?ProductReview
    {
        if (mb_strlen($data['text']) < 20) {
            return null;
        }

        foreach ($this->stopWords as $word) {
            if (mb_stripos($data['text'], $word) !== false) {
                return null;
            }
        }

        return ProductReview::create([
            'product_id' => $productId,
            'source' => $source,
            'external_id' => $data['external_id'],
            'author' => $this->anonymizeAuthor($data['author']),
            'rating' => max(1, min(5, (int) $data['rating'])),
            'text' => $this->sanitize($data['text']),
            'pros' => $this->sanitize($data['pros'] ?? ''),
            'cons' => $this->sanitize($data['cons'] ?? ''),
            'date' => $data['date'],
            'is_verified' => $data['verified'] ?? false,
            'helpful' => $data['helpful'] ?? 0,
            'status' => 'pending',
        ]);
    }

    private function anonymizeAuthor(string $name): string
    {
        $parts = explode(' ', trim($name));
        if (count($parts) >= 2) {
            return $parts[0] . ' ' . mb_substr($parts[1], 0, 1) . '.';
        }
        return $name ?: 'Покупатель';
    }

    private function sanitize(string $text): string
    {
        return strip_tags(trim($text));
    }
}

נתונים מובנים לקידום אתרים

לאחר הייבוא, ביקורות מתפרסמות ב-JSON-LD בדף המוצר. זה מגדיל את הסיכוי להופיע ב-rich snippets ומגביר את ה-CTR ב-20-30%. למידע נוסף על נתונים מובנים.

// app/Http/Controllers/ProductController.php
public function show(string $slug): Response
{
    $product = Product::withReviews()->findBySlug($slug);
    $reviewSchema = $product->reviews->map(fn($r) => [
        '@type' => 'Review',
        'author' => ['@type' => 'Person', 'name' => $r->author],
        'datePublished' => $r->date,
        'reviewBody' => $r->text,
        'reviewRating' => [
            '@type' => 'Rating',
            'ratingValue' => $r->rating,
            'bestRating' => 5,
        ],
    ]);
    $aggregateRating = [
        '@type' => 'AggregateRating',
        'ratingValue' => round($product->reviews->avg('rating'), 1),
        'reviewCount' => $product->reviews->count(),
    ];
}

איך להימנע מחסימות בזמן גירוד?

כדי להימנע מחסימות, אנו משתמשים במאגר של 50+ פרוקסי מגורים, עיכובים אקראיים של 1 עד 4 שניות, וסיבוב User-Agent (Chrome, Firefox, Safari). CAPTCHA נפתרים דרך Anti-Captcha. כל סשן מוגבל ל-1000 ביקורות.

למה אוטומציה של ביקורות משפרת קידום אתרים?

  • נתונים מובנים (JSON-LD) עוזרים למנועי חיפוש להציג דירוגים ב-snippets.
  • טקסטים של UGC מכילים מילות מפתח ארוכות זנב.
  • עדכונים קבועים מאותתים על חנות פעילה.

השוואה: איסוף ידני של 100 ביקורות לוקח שעתיים, הפארסר שלנו — 2 דקות, מהיר פי 60. חיסכון בתקציב על כותבי תוכן ומנחים — עד 70%.

תהליך העבודה

  1. ניתוח: קביעת פלטפורמות, APIs, מורכבות.
  2. פיתוח: כתיבת פארסר, מודרציה, הסרת כפילויות.
  3. בדיקות: הרצה על 1000+ ביקורות, בדיקת באגים.
  4. פריסה: הגדרת cron, ניטור שגיאות.
  5. תיעוד: תיאור מחסנית, הוראות הפעלה.
שלב משך
ניתוח דרישות 1-2 ימים
פיתוח פארסר 2-3 ימים לכל פלטפורמה
בדיקות 1-2 ימים
פריסה ותיעוד יום אחד

מחיר התחלתי לפארסר לפלטפורמה אחת הוא $500, עם הנחות לכמויות. אנו מבטיחים ביצועים אמינים, עם ניסיון של למעלה מ-5 שנים ופרקטיקות גירוד מוסמכות. בוט הפארסר לביקורות שלנו מטפל באגרגציה של ביקורות ממספר מקורות, ומבטיח שכל הנתונים מיובאים כראוי.

מה כלול

  • פארסר לכל פלטפורמת מסחר (עד 5 פלטפורמות).
  • מודרציה (מילות עצירה, אורך, אנונימיזציה).
  • הסרת כפילויות (לפי external_id + source).
  • עדכונים אוטומטיים בלוח זמנים (יומי או כל 4 שעות).
  • נתונים מובנים בדף המוצר.
  • רישום והתראות שגיאות.

לוח זמנים: מ-3 עד 5 ימי עסקים לכל פלטפורמה. לפרויקט מורכב (3 פלטפורמות + מודרציה + SEO) — 7-10 ימים. צרו קשר כדי להעריך את הפרויקט שלכם. קבלו ייעוץ לפרויקט שלכם.