
Умный покупатель
Сравнение цен на Wildberries, Ozon и Яндекс Маркет через браузер. Цена за единицу, выявление накрученных отзывов, история цен и стоимость доставки — рекомендует лучшее предложение.
SKILL.md
Умный покупатель — сравнение цен на маркетплейсах
Сравниваем цены на Wildberries, Ozon и Яндекс Маркет в реальном времени. Открываем браузер, ищем товар на всех трёх площадках, извлекаем цены, отзывы, условия доставки — и рекомендуем лучшее предложение.
Установка browser-use
Для работы этого навыка необходим browser-use.
Если browser-use не установлен — активируй навык browser-use и следуй его инструкциям.
Он автоматически установит Python, pip и browser-use для твоей платформы.
Пока идёт установка, скажи: «Настраиваю поиск, это займёт пару минут...» НЕ показывай пользователю команды, ошибки или технические детали.
Когда использовать
- Пользователь спрашивает «Где дешевле купить...?»
- Пользователь даёт название товара или ссылку с одного маркетплейса
- Пользователь хочет сравнить цены перед покупкой
- Пользователь просит оценить «выгодная ли цена?»
- Пользователь хочет проверить отзывы на товар
Workflow 1: Поиск по названию товара
Пользователь даёт название товара. Ищем на всех трёх площадках одновременно.
Шаг 1: Подготовка
# Закрыть все предыдущие сессии
browser-use close --all
sleep 1
Шаг 2: Wildberries
# Открыть поиск Wildberries
browser-use --headed open "https://www.wildberries.ru/catalog/0/search.aspx?search=QUERY"
sleep 4
browser-use state
URL-паттерны Wildberries:
| Действие | URL |
|---|---|
| Поиск | https://www.wildberries.ru/catalog/0/search.aspx?search=<запрос> |
| Карточка товара | https://www.wildberries.ru/catalog/<ID>/detail.aspx |
| Отзывы | https://www.wildberries.ru/catalog/<ID>/otzyvy |
Извлечение данных через eval:
# Получить список товаров (первые 5)
browser-use eval "JSON.stringify(Array.from(document.querySelectorAll('.product-card__wrapper, [class*=\"product-card\"]')).slice(0,5).map(el => ({name: el.querySelector('.product-card__name, [class*=\"goods-name\"]')?.textContent?.trim(), price: el.querySelector('.product-card__price, [class*=\"lower-price\"], [class*=\"price\"]')?.textContent?.trim(), oldPrice: el.querySelector('.product-card__old-price, [class*=\"old-price\"]')?.textContent?.trim(), rating: el.querySelector('.product-card__rating, [class*=\"rating\"]')?.textContent?.trim(), reviews: el.querySelector('.product-card__reviews, [class*=\"reviews-count\"]')?.textContent?.trim(), link: el.querySelector('a.product-card__link, a[href*=\"/catalog/\"]')?.href})))"
Селекторы Wildberries:
| Элемент | CSS селектор |
|---|---|
| Карточка товара | .product-card__wrapper, [class*="product-card"] |
| Название | .product-card__name, [class*="goods-name"] |
| Текущая цена | .product-card__price, [class*="lower-price"] |
| Старая цена (без скидки) | .product-card__old-price, [class*="old-price"] |
| Рейтинг | .product-card__rating, [class*="rating"] |
| Количество отзывов | .product-card__reviews, [class*="reviews-count"] |
| Ссылка на товар | a.product-card__link, a[href*="/catalog/"] |
| Бренд | .product-card__brand, [class*="brand-name"] |
Особенности Wildberries:
- Цена может отображаться с картой WB (скидка) и без — извлекай обе
- Сортировка по цене: добавь параметр
&sort=priceascк URL поиска - Сортировка по популярности:
&sort=popular - Wildberries — тяжёлый SPA, жди 4-5 секунд после загрузки
Шаг 3: Ozon
# Открыть поиск Ozon
browser-use --headed open "https://www.ozon.ru/search/?text=QUERY"
sleep 4
browser-use state
URL-паттерны Ozon:
| Действие | URL |
|---|---|
| Поиск | https://www.ozon.ru/search/?text=<запрос> |
| Карточка товара | https://www.ozon.ru/product/<slug>-<ID>/ |
| Отзывы | https://www.ozon.com/product/<slug>-<ID>/reviews/ |
Извлечение данных через eval:
# Получить список товаров (первые 5)
browser-use eval "JSON.stringify(Array.from(document.querySelectorAll('[class*=\"tile\"], [data-widget=\"searchResultsV2\"] [class*=\"item\"]')).slice(0,5).map(el => ({name: el.querySelector('[class*=\"title\"], [class*=\"productName\"], a[class*=\"tile\"] span')?.textContent?.trim(), price: el.querySelector('[class*=\"price\"], [class*=\"Price\"]')?.textContent?.trim()?.replace(/\\s+/g,' '), oldPrice: el.querySelector('[class*=\"oldPrice\"], [class*=\"crossed\"]')?.textContent?.trim(), rating: el.querySelector('[class*=\"stars\"], [class*=\"rating\"]')?.textContent?.trim(), reviews: el.querySelector('[class*=\"review\"], [class*=\"count\"]')?.textContent?.trim(), link: el.querySelector('a[href*=\"/product/\"]')?.href})))"
Селекторы Ozon:
| Элемент | CSS селектор |
|---|---|
| Карточка товара | [class*="tile"], [data-widget="searchResultsV2"] [class*="item"] |
| Название | [class*="title"], [class*="productName"] |
| Цена (с картой Ozon) | [class*="price"], [class*="Price"] |
| Цена без карты | [class*="oldPrice"], [class*="crossed"] |
| Рейтинг | [class*="stars"], [class*="rating"] |
| Ссылка на товар | a[href*="/product/"] |
Особенности Ozon:
- Цена с картой Ozon Savings и без — часто разница 5-15%
- Ozon использует динамические CSS-классы с хешами — selectors могут меняться
- Если eval возвращает пустой результат — сделай
browser-use stateдля актуальной структуры DOM - Ozon Premium badge — товары с премиум-доставкой (бесплатная доставка)
Шаг 4: Яндекс Маркет
# Открыть поиск Яндекс Маркет
browser-use --headed open "https://market.yandex.ru/search?text=QUERY"
sleep 4
browser-use state
URL-паттерны Яндекс Маркет:
| Действие | URL |
|---|---|
| Поиск | https://market.yandex.ru/search?text=<запрос> |
| Карточка товара | https://market.yandex.ru/product/<ID> |
| Сравнение цен | https://market.yandex.ru/product/<ID>/offers |
| Отзывы | https://market.yandex.ru/product/<ID>/reviews |
| История цен | https://market.yandex.ru/product/<ID> (вкладка «Цены») |
Извлечение данных через eval:
# Получить список товаров (первые 5)
browser-use eval "JSON.stringify(Array.from(document.querySelectorAll('[class*=\"search-result\"], [data-auto*=\"searchResult\"]')).slice(0,5).map(el => ({name: el.querySelector('[class*=\"title\"], [data-auto*=\"title\"], h3')?.textContent?.trim(), price: el.querySelector('[class*=\"price\"], [data-auto*=\"price\"]')?.textContent?.trim(), oldPrice: el.querySelector('[class*=\"old-price\"], [class*=\"without-badge\"]')?.textContent?.trim(), rating: el.querySelector('[class*=\"rating\"], [class*=\"stars\"]')?.textContent?.trim(), reviews: el.querySelector('[class*=\"review\"], [class*=\"count\"]')?.textContent?.trim(), shop: el.querySelector('[class*=\"shop\"], [class*=\"seller\"]')?.textContent?.trim(), link: el.querySelector('a[href*=\"/product/\"]')?.href})))"
Селекторы Яндекс Маркет:
| Элемент | CSS селектор |
|---|---|
| Карточка товара | [class*="search-result"], [data-auto*="searchResult"] |
| Название | [class*="title"], [data-auto*="title"], h3 |
| Цена | [class*="price"], [data-auto*="price"] |
| Рейтинг | [class*="rating"], [class*="stars"] |
| Продавец/магазин | [class*="shop"], [class*="seller"] |
| Ссылка на товар | a[href*="/product/"] |
Особенности Яндекс Маркет:
- Яндекс Маркет — агрегатор: один и тот же товар могут продавать разные магазины
- Страница «Все предложения» (
/offers) показывает все цены на один товар - Есть встроенная история цен — показывает была ли скидка реальной
- Рейтинг основан на реальных отзывах с подтверждением покупки
Шаг 5: Сравнение и результат
После сбора данных со всех трёх площадок — сравни и выведи результат:
Сравнение цен: [Название товара]
| Площадка | Цена | Без скидки | Рейтинг | Отзывы | Доставка |
|----------|------|------------|---------|--------|----------|
| Wildberries | 1 299 ₽ | 1 890 ₽ | 4.7 | 342 | 1-2 дня, бесплатно от 500₽ |
| Ozon | 1 450 ₽ | 1 690 ₽ | 4.5 | 218 | 1-3 дня, бесплатно с Premium |
| Яндекс Маркет | 1 190 ₽ | 1 750 ₽ | 4.8 | 501 | 1 день, бесплатно от 300₽ |
Выгоднее всего: Яндекс Маркет — 1 190 ₽ (экономия 260₽ vs Wildberries)
Цена за единицу:
- Wildberries: 65 ₽/шт
- Ozon: 73 ₽/шт
- Яндекс Маркет: 60 ₽/шт
Workflow 2: Поиск по ссылке
Пользователь даёт ссылку с одного маркетплейса. Нужно найти тот же товар на двух других.
Шаг 1: Извлечь данные из исходной ссылки
# Открыть ссылку пользователя
browser-use --headed open "<URL_пользователя>"
sleep 4
browser-use state
Извлечь ключевые данные:
# Wildberries — извлечь название и артикул
browser-use eval "JSON.stringify({name: document.querySelector('.product-page__header, [class*=\"product-name\"]')?.textContent?.trim(), brand: document.querySelector('.product-page__brand, [class*=\"brand\"]')?.textContent?.trim(), article: document.querySelector('[class*=\"article\"], [class*=\"vendor-code\"]')?.textContent?.trim(), price: document.querySelector('.product-page__price, [class*=\"lower-price\"]')?.textContent?.trim()})"
# Ozon — извлечь название
browser-use eval "JSON.stringify({name: document.querySelector('h1, [class*=\"title\"]')?.textContent?.trim(), price: document.querySelector('[class*=\"price\"]')?.textContent?.trim()})"
# Яндекс Маркет — извлечь название
browser-use eval "JSON.stringify({name: document.querySelector('h1, [class*=\"title\"]')?.textContent?.trim(), price: document.querySelector('[class*=\"price\"]')?.textContent?.trim()})"
Шаг 2: Поиск на других площадках
Используй название товара + бренд как поисковый запрос на двух других площадках.
# Закрыть текущую вкладку
browser-use close
# Искать на следующей площадке
browser-use --headed open "https://www.wildberries.ru/catalog/0/search.aspx?search=<название+бренд>"
sleep 4
# ... (извлечение данных как в Workflow 1)
Шаг 3: Сопоставление товаров
При сопоставлении одного и того же товара на разных площадках проверяй:
- Название — совпадает ли бренд и модель
- Характеристики — вес, объём, комплектация
- Артикул/модель — если указан
- Фото — похоже ли (можно использовать image_analysis)
Важно: Не все товары есть на всех площадках. Если товар не найден — сообщи об этом.
Workflow 3: Проверка истории цен
Проверяем, была ли цена ниже и стоит ли ждать скидку.
Через Яндекс Маркет
# Открыть карточку товара на Яндекс Маркет
browser-use --headed open "https://market.yandex.ru/product/<ID>"
sleep 4
# Попробовать найти график цены или вкладку «История цен»
browser-use state
# Если есть вкладка/секция с историей цен — кликнуть
browser-use click "text=История цен"
sleep 2
browser-use state
Через web_search
# Использовать web_search для поиска истории цен
web_search "цена история [название товара] [маркетплейс] 2025 2026"
Поиск по сайтам-трекерам цен:
eking.ru— история цен Wildberries и Ozontx24.ru— трекер цен маркетплейсовdiscounthunter.ru— история скидок
Через web_reader
# Прочитать страницу трекера цен
web_reader https://eking.ru/search?query=<название+товара>
Анализ ценовой истории
Скажи пользователю:
История цен: [Название товара]
Текущая цена: 1 299 ₽
Минимальная за 6 месяцев: 899 ₽ (октябрь 2025)
Максимальная за 6 месяцев: 1 890 ₽ (декабрь 2025)
Средняя цена: 1 350 ₽
Вердикт: Цена сейчас ниже средней, но выше минимальной.
Если не горит — подожди до [ближайшая распродажа], скидки бывают каждые 2-3 недели.
Workflow 4: Анализ отзывов и обнаружение накрутки
Извлечение отзывов
Wildberries:
# Перейти к отзывам
browser-use open "https://www.wildberries.ru/catalog/<ID>/otzyvy"
sleep 3
# Извлечь отзывы
browser-use eval "JSON.stringify(Array.from(document.querySelectorAll('[class*=\"feedback\"], [class*=\"review\"]')).slice(0,20).map(el => ({rating: el.querySelector('[class*=\"stars\"], [class*=\"rating\"]')?.textContent?.trim(), text: el.querySelector('[class*=\"text\"], [class*=\"body\"]')?.textContent?.trim()?.substring(0,200), author: el.querySelector('[class*=\"author\"], [class*=\"name\"]')?.textContent?.trim(), date: el.querySelector('[class*=\"date\"]')?.textContent?.trim()})))"
Ozon:
# На странице товара найти секцию отзывов
browser-use eval "document.querySelectorAll('[class*=\"review\"], [class*=\"feedback\"]').length"
# Если отзывов много — кликнуть «Все отзывы»
browser-use click "text=Все отзывы"
sleep 3
# Извлечь отзывы
browser-use eval "JSON.stringify(Array.from(document.querySelectorAll('[class*=\"review\"]')).slice(0,20).map(el => ({rating: el.querySelector('[class*=\"stars\"]')?.getAttribute('class')?.match(/(\\d)/)?.[1], text: el.querySelector('[class*=\"text\"]')?.textContent?.trim()?.substring(0,200), author: el.querySelector('[class*=\"author\"], [class*=\"name\"]')?.textContent?.trim(), date: el.querySelector('[class*=\"date\"]')?.textContent?.trim()})))"
Признаки накрученных отзывов
Проверяй эти паттерны при анализе:
| Признак | Описание | Вес |
|---|---|---|
| Идентичный текст | 3+ отзыва с одинаковым текстом (с точностью до 2-3 слов) | Высокий |
| Короткие хвалебные | «Отличный товар!», «Всем советую!», «Супер!» — без конкретики | Средний |
| Подозрительные авторы | Авторы только с 1 отзывом, аккаунт создан недавно | Средний |
| Пачка отзывов в один день | 10+ отзывов в одну дату, потом тишина | Высокий |
| Нерелевантные фото | Фото явно не от этого товара или стоковые | Высокий |
| Противоречие рейтингу | Много 5-звёздочных, но конкретные жалобы в 3-звёздочных указывают на реальные проблемы | Средний |
| Купленные отзывы | Фразы «получил товар бесплатно за отзыв» — это честно, но учитывай что оценка может быть завышена | Низкий |
Вывод анализа отзывов
Анализ отзывов: [Название товара]
Wildberries: 4.7 (342 отзыва)
- Подозрительных: ~15% (52 отзыва)
- Реальный рейтинг: ~4.3 (скорректированный)
Ozon: 4.5 (218 отзывов)
- Подозрительных: ~8% (17 отзывов)
- Реальный рейтинг: ~4.4 (скорректированный)
Яндекс Маркет: 4.8 (501 отзыв)
- Подозрительных: ~5% (25 отзывов)
- Реальный рейтинг: ~4.7 (скорректированный)
Вердикт: На Wildberries заметна накрутка. Яндекс Маркет вызывает больше доверия.
Расчёт цены за единицу
Сравнение цены за единицу — честнее чем сравнение полной цены.
# Извлечь вес/объём из названия или характеристик
browser-use eval "const t = document.querySelector('h1, [class*=\"title\"]')?.textContent || ''; const m = t.match(/(\\d+[.,]?\\d*)\\s*(мл|л|г|кг|шт|упак|капс|таб|пакет|рулон)/i); m ? m[0] : 'unknown'"
Правила расчёта
| Единица | Конвертация | Пример |
|---|---|---|
| мл | ×1 | 500 мл = 500 единиц |
| л | ×1000 → мл | 1.5 л = 1500 мл |
| г | ×1 | 400 г = 400 единиц |
| кг | ×1000 → г | 0.5 кг = 500 г |
| шт | ×1 | 20 шт = 20 единиц |
| упак | разобрать что внутри | 6 шт × 5 упак = 30 шт |
| капс | ×1 | 30 капсул = 30 единиц |
| таб | ×1 | 60 таблеток = 60 единиц |
Формула: Цена за единицу = Цена / Количество единиц
Оценка стоимости доставки
Wildberries
- Доставка до пункта выдачи: бесплатно при заказе от 500₽ (в Depends on location)
- Доставка курьером: от 199₽
- Экспресс-доставка: от 299₽
- Срок: 1-2 дня обычно
Ozon
- Доставка до пункта выдачи: бесплатно с Ozon Premium (подписка)
- Без Premium: от 49₽ при заказе от 600₽
- Доставка курьером: от 99₽ (бесплатно с Premium)
- Срок: 1-5 дней в зависимости от региона
Яндекс Маркет
- Доставка: бесплатно от 300-500₽ (зависит от продавца)
- Экспресс: от 199₽
- Срок: от 1 дня (Москва, СПб), 2-5 дней (регионы)
- Яндекс Плюс: бесплатная доставка на многие товары
При расчёте итоговой стоимости учитывай доставку:
Итоговая стоимость (с доставкой):
- Wildberries: 1 299 ₽ + 0 ₽ = 1 299 ₽
- Ozon: 1 450 ₽ + 99 ₽ = 1 549 ₽ (без Premium)
- Яндекс Маркет: 1 190 ₽ + 0 ₽ = 1 190 ₽
Оценка «Выгодная ли покупка?»
Методика оценки
- Сравни с средней ценой — если ниже средней на 15%+ — выгодно
- Проверь историю цен — если цена близка к минимуму — отлично
- Учти цену за единицу — большая упаковка часто дешевле за единицу
- Проверь аналоги — может, похожий товар стоит в 2 раза дешевле
- Учти доставку — дорогой товар с бесплатной доставкой может быть выгоднее дешёвого с платной
Вердикт
| Оценка | Условие |
|---|---|
| Отличная цена | ниже минимума за 6 месяцев или ниже средней на 20%+ |
| Хорошая цена | ниже средней на 5-20% |
| Нормальная цена | в пределах +/- 5% от средней |
| Дорого | выше средней на 5-20% |
| Переплата | выше средней на 20%+ или выше максимума за 6 месяцев |
Использование web_search для оценки
web_search "цена [название товара] отзывы обзор 2025 2026"
Ищи обзоры и сравнения — они часто указывают справедливую цену.
JavaScript Eval Snippets
Универсальные проверки
# Сколько товаров в выдаче?
browser-use eval "document.querySelectorAll('[class*=\"product-card\"], [class*=\"tile\"], [class*=\"search-result\"]').length"
# Название первого товара
browser-use eval "document.querySelector('[class*=\"product-name\"], [class*=\"title\"], h3')?.textContent?.trim()"
# Цена первого товара
browser-use eval "document.querySelector('[class*=\"price\"]')?.textContent?.trim()?.substring(0, 30)"
# Рейтинг
browser-use eval "document.querySelector('[class*=\"rating\"], [class*=\"stars\"]')?.textContent?.trim()"
Wildberries — детальное извлечение
# Цена с картой и без
browser-use eval "const card = document.querySelector('[class*=\"lower-price\"]')?.textContent?.trim(); const noCard = document.querySelector('[class*=\"old-price\"]')?.textContent?.trim(); JSON.stringify({withCard: card, withoutCard: noCard})"
# Количество отзывов
browser-use eval "document.querySelector('[class*=\"reviews-count\"], [class*=\"feedback-count\"]')?.textContent?.trim()"
# Бренд
browser-use eval "document.querySelector('[class*=\"brand\"]')?.textContent?.trim()"
# Полная информация о первом товаре
browser-use eval "const c = document.querySelector('[class*=\"product-card\"]'); JSON.stringify({name: c?.querySelector('[class*=\"goods-name\"], [class*=\"name\"]')?.textContent?.trim(), price: c?.querySelector('[class*=\"lower-price\"]')?.textContent?.trim(), oldPrice: c?.querySelector('[class*=\"old-price\"]')?.textContent?.trim(), rating: c?.querySelector('[class*=\"rating\"]')?.textContent?.trim(), reviews: c?.querySelector('[class*=\"reviews-count\"]')?.textContent?.trim(), link: c?.querySelector('a')?.href})"
Ozon — детальное извлечение
# Цена с Ozon Card и без
browser-use eval "const prices = document.querySelectorAll('[class*=\"Price\"]'); JSON.stringify({current: prices[0]?.textContent?.trim(), old: prices[1]?.textContent?.trim()})"
# Название и бренд
browser-use eval "const t = document.querySelector('[class*=\"title\"]')?.textContent?.trim(); JSON.stringify({full: t})"
# Данные первого товара в выдаче
browser-use eval "const c = document.querySelector('[class*=\"tile\"]'); JSON.stringify({name: c?.querySelector('[class*=\"title\"]')?.textContent?.trim(), price: c?.querySelector('[class*=\"Price\"]')?.textContent?.trim(), rating: c?.querySelector('[class*=\"stars\"]')?.textContent?.trim(), link: c?.querySelector('a')?.href})"
Яндекс Маркет — детальное извлечение
# Все предложения на товар
browser-use eval "JSON.stringify(Array.from(document.querySelectorAll('[class*=\"offer\"]')).slice(0,10).map(el => ({price: el.querySelector('[class*=\"price\"]')?.textContent?.trim(), shop: el.querySelector('[class*=\"shop\"], [class*=\"seller\"]')?.textContent?.trim(), rating: el.querySelector('[class*=\"rating\"]')?.textContent?.trim()})))"
# Минимальная цена из предложений
browser-use eval "Math.min(...Array.from(document.querySelectorAll('[class*=\"offer\"] [class*=\"price\"]')).map(el => parseInt(el.textContent.replace(/\\D/g, ''))).filter(n => !isNaN(n)))"
Правила: state vs eval
browser-use state дампит весь DOM страницы. Маркетплейсы — очень тяжёлые SPA с тысячами элементов. State занимает 10-30 секунд и забивает контекст.
Делай state
- В начале работы с каждой новой площадкой (определить структуру)
- Когда eval возвращает неожиданный результат (DOM изменился)
- При навигации на новую страницу (поиск → карточка товара)
- Когда нужно найти индекс элемента для
click
НЕ делай state
- Для получения цены (используй eval)
- Для получения названия товара (используй eval)
- Для проверки загрузки страницы (используй eval)
- Для извлечения списка товаров (используй eval)
- Между одинаковыми операциями (поиск → поиск → поиск)
Быстрые eval-проверки вместо state
# Загрузились товары?
browser-use eval "document.querySelectorAll('[class*=\"product-card\"], [class*=\"tile\"], [class*=\"search-result\"]').length > 0"
# Цена конкретного товара
browser-use eval "document.querySelector('[class*=\"price\"]')?.textContent?.match(/[\\d\\s]+/)?.[0]?.trim()"
# Название товара
browser-use eval "document.querySelector('h1, [class*=\"title\"]')?.textContent?.trim()?.substring(0, 100)"
Поделиться результатом сравнения
Формат «Карточка сравнения»
СРАВНЕНИЕ ЦЕН
Товар: [Название]
Дата: [Сегодня]
+------------------+----------+----------+--------+----------+
| Площадка | Цена | Скидка | Рейтинг| Доставка |
+------------------+----------+----------+--------+----------+
| Wildberries | X XXX ₽ | -XX% | X.X * | X дней |
| Ozon | X XXX ₽ | -XX% | X.X * | X дней |
| Яндекс Маркет | X XXX ₽ | -XX% | X.X * | X дней |
+------------------+----------+----------+--------+----------+
Цена за единицу: от XX ₽/шт (Яндекс Маркет) до XX ₽/шт (Ozon)
ЛУЧШЕЕ ПРЕДЛОЖЕНИЕ: [Площадка] — X XXX ₽
Экономия: XXX ₽ vs самое дорогое
Вердикт: [Отличная/Хорошая/Нормальная] цена. [Комментарий]
История цен: мин. XXX ₽, макс. X XXX ₽, средняя X XXX ₽ за 6 мес.
Отзывы: [Оценка достоверности отзывов]
Fallback: данные не извлекаются
Маркетплейсы — тяжёлые SPA с динамическими классами, селекторы ломаются. Если browser-use eval вернул пусто, null или NaN:
- Сначала — упрощённый/универсальный eval (см. «JavaScript Eval Snippets»):
document.querySelector('[class*="price"]')?.textContent. - Не помогло —
browser-use screenshotкарточки товара →image_analysis(prompt="Извлеки название, цену, старую цену, рейтинг и число отзывов"). Это надёжнееstateи не забивает контекст. - Только потом —
browser-use state(последнее средство: 10–30 сек, тысячи элементов).
Никогда не пиши «цена не найдена», не попробовав screenshot + image_analysis. Не выдумывай цифры — лучше честно сказать, что на одной площадке товар не нашёлся.
Обработка ошибок
| Проблема | Решение |
|---|---|
| Товар не найден на одной из площадок | Напиши «На [площадка] товар не найден». Сравни только найденные. |
| CAPTCHA на Wildberries | Подожди 30 секунд, обнови. Попроси пользователя пройти вручную в headed-режиме. |
| Страница долго грузится | Увеличь sleep до 5-6 секунд. Все три площадки — тяжёлые SPA. |
| Цена не извлекается | Сделай browser-use state для актуальной структуры DOM. Селекторы могли измениться. |
| Разные товары в выдаче | Уточни запрос: добавь бренд, модель, артикул. Сравнивай только идентичные товары. |
| Модальное окно блокирует | browser-use eval "document.querySelector('[class*=\"modal\"], [class*=\"popup\"]')?.querySelector('[class*=\"close\"], [aria-label=\"Закрыть\"]')?.click()" |
| Сессия зависла | browser-use close --all, начни заново. |
| Wildberries показывает регион другой | Выбор города — через eval кликнуть на город в шапке и выбрать нужный. |
| Ozon: нет результатов | Ozon чувствителен к кириллице в URL. Попробуй латиницу или другой формат запроса. |
| Яндекс Маркет: требуется вход | Некоторые данные видны только авторизованным. Попроси пользователя войти. |
| Цены в разной валюте | Все три площадки показывают цены в рублях. Если видишь другую валюту — это баг парсинга. |
| Некорректные символы в URL | Кодируй кириллицу: encodeURI('ноутбук') → %D0%BD%D0%BE%D1%83%D1%82%D0%B1%D1%83%D0%BA |
| «Element not found» после навигации | DOM перерисовался — делай state заново для свежих индексов. |
Использование image_analysis
Для анализа фотографий товаров (полезно при сопоставлении одинаковых товаров):
# Получить URL изображения товара
browser-use eval "document.querySelector('[class*=\"image\"] img, [class*=\"photo\"] img, img[class*=\"product\"]')?.src"
Затем используй image_analysis с параметрами:
imageSource: URL изображения товараprompt: «Опиши товар на фото: категория, бренд, модель, цвет, размер, состояние упаковки»
Оптимизация для повторных запросов
Если пользователь просит сравнить цены на несколько товаров подряд:
- Не закрывай браузер между запросами — переходи по новому URL поиска
- Используй один профиль для сохранения авторизации:
browser-use --profile "shopper" - Кешируй структуру DOM — если площадка не обновлялась, селекторы те же
- Группируй запросы — если 3+ товара, спрашивай «Сравнить все сразу или по очереди?»
Cleanup
browser-use close # закрыть текущую сессию
browser-use close --all # закрыть ВСЕ сессии (использовать после завершения сравнения)
Советы
- Всегда
close --allпервым — старые сессии — причина #1 зависаний - Жди 4-5 секунд после навигации — маркетплейсы — очень тяжёлые SPA
- Проверяй модалки перед действиями — Wildberries и Ozon любят всплывающие окна
- Используй eval вместо state — eval в 10 раз быстрее и не забивает контекст
- Сравнивай цену за единицу — а не полную цену, для честного сравнения
- Проверяй отзывы на накрутку — особенно на Wildberries
- Учитывай стоимость доставки — дорогой товар с бесплатной доставкой может быть выгоднее
- Проверяй историю цен перед покупкой — скидка может быть ненастоящей
- Не забывай про аналоги — похожий товар другого бренда может быть в 2 раза дешевле
- Упрощай поисковые запросы — «Ноутбук ASUS VivoBook 15 X515EA-BQ» → «ASUS VivoBook 15 X515EA»