ZeroPost
Все статьи

Строим AI-агента для мониторинга цен: Perplexity API + Google Sheets

ZeroPost AI8 июля 2026 г. 4 мин чтения
Строим AI-агента для мониторинга цен: Perplexity API + Google Sheets

Сижу вечером, листаю маркетплейсы. Товар, который присмотрел, стоит то 12 900, то 14 200, то внезапно 11 500 — и непонятно, это скидка или просто наценка в выходные. Короче, решил я это автоматизировать. Заодно разобраться с Perplexity API, который всё хвалят за свежие данные из сети.

Что получилось: скрипт, который раз в сутки дёргает Perplexity, просит его найти актуальную цену на товар, и результат складывает в Google Sheets с датой. За неделю накопилось достаточно данных, чтобы понять паттерн.

Почему Perplexity, а не обычный парсинг

Классический подход — написать парсер сайта, подсунуть его в cron, радоваться. Проблема в том, что маркетплейсы очень агрессивно банят ботов. Cloudflare, капча, постоянные изменения вёрстки. Полчаса настроил — через неделю всё сломалось.

Perplexity решает это иначе: он уже лазит по сети и возвращает структурированный ответ. API стоит денег, но для пары десятков товаров выходит копейки. Запрос вида «найди цену видеокарты RTX 4070 на Ozon, Wildberries и DNS сегодня» отрабатывает за пару секунд и возвращает чистый JSON.

Настраиваем Perplexity API

Регистрируемся на docs.perplexity.ai. Дают бесплатных 5 долларов на старте — хватает надолго, если не дёргать по 1000 раз в день. Берём ключ, сохраняем.

Из доступных моделей я остановился на sonar — заточен под поиск, работает быстро. Есть sonar-reasoning (дороже, медленнее, но точнее) и sonar-pro (ещё дороже). Для ценника всё это overkill.

Простой запрос выглядит так:

import requests

url = "https://api.perplexity.ai/chat/completions"
headers = {
    "Authorization": f"Bearer {PERPLEXITY_API_KEY}",
    "Content-Type": "application/json"
}
payload = {
    "model": "sonar",
    "messages": [
        {
            "role": "system",
            "content": "Ты парсишь цены с российских маркетплейсов. Отвечай ТОЛЬКО в JSON формате: {\"source\": \"название\", \"price\": число, \"currency\": \"RUB\"}"
        },
        {
            "role": "user",
            "content": "Найди текущую цену iPhone 15 128GB на Ozon и Wildberries"
        }
    ]
}

response = requests.post(url, json=payload, headers=headers)
print(response.json()["choices"][0]["message"]["content"])

У меня с первого раза сработало. Ну, почти — в первый раз я забыл системный промпт и получил развёрнутый текст вместо JSON, который потом пришлось парсить регуляркой. Не повторяйте.

Прикручиваем Google Sheets

Создаём таблицу с колонками: Дата, Товар, Источник, Цена, Комментарий.

Дальше — авторизация. Идём в Google Cloud Console, создаём проект, включаем Google Sheets API, генерируем Service Account, скачиваем JSON-ключ.

Устанавливаем gspread:

pip install gspread oauth2client

И подключаемся:

import gspread
from oauth2client.service_account import ServiceAccountCredentials

scope = ["https://spreadsheets.google.com/feeds",
         "https://www.googleapis.com/auth/drive"]

creds = ServiceAccountCredentials.from_json_keyfile_name(
    "service_account.json", scope
)
client = gspread.authorize(creds)

sheet = client.open("Мониторинг цен").sheet1

Добавить строку — одна команда:

sheet.append_row([
    "2025-01-15",
    "iPhone 15 128GB",
    "Ozon",
    "79990",
    ""
])

Шарим таблицу на email сервис-аккаунта (он там в JSON-ключе, поле client_email). Без этого будет 403.

Собираем всё в одного агента

Склеиваем всё в один скрипт. Список товаров — в YAML-файле, чтобы не править код каждый раз:

# products.yaml
products:
  - name: "iPhone 15 128GB"
    sources: ["Ozon", "Wildberries", "DNS"]
  - name: "iPhone 15 256GB"
    sources: ["Ozon", "Wildberries"]
  - name: "PlayStation 5"
    sources: ["Ozon", "Wildberries", "MVideo"]

Сам агент — простой цикл:

import json
from datetime import datetime
import gspread

def get_price(product_name, source):
    # запрос к Perplexity
    ...
    return int(price_str.replace(" ", "").replace("₽", ""))

for product in products:
    for source in product["sources"]:
        try:
            price = get_price(product["name"], source)
            sheet.append_row([
                datetime.now().strftime("%Y-%m-%d"),
                product["name"],
                source,
                price,
                ""
            ])
        except Exception as e:
            print(f"Ошибка {product['name']} {source}: {e}")

Вешаем на cron — 0 9 * * * — и каждое утро получаем свежую порцию данных.

Где я наступил на грабли

Первая проблема: Perplexity иногда возвращает «по данным на вчера» или просто не находит товар. Срабатывает примерно в 10–15% случаев. Решение — retry с задержкой в 30 секунд, и если второй раз не получилось, пишу в комментарий «нет данных».

Вторая: цену sometimes возвращает как «79 990 ₽», sometimes как «79990». Убираю все нецифровые символы перед конвертацией в int.

Третья, глупая: забыл поставить ограничение на количество запросов в минуту. Запустил тест в цикле — выжег дневной бюджет за пять минут. Теперь в коде стоит time.sleep(3) между запросами.

Что получилось за неделю

Семь дней, три товара, два источника. Данных пока мало для серьёзных выводов, но паттерн уже виден: Ozon стабильно дешевле Wildberries на 2–5%, а DNS дороже всех. iPhone 15 128GB плавает в диапазоне 78 500–82 000. Скидки появляются по вторникам и пятницам — совпадение или маркетплейсовая закономерность, пока неясно.

Дальше хочу прикрутить простую визуализацию — график в той же таблице через встроенные диаграммы Google Sheets. И, может быть, уведомление в Telegram, если цена упала ниже заданного порога. Это уже ближе к настоящему агенту, а не просто скрипту по расписанию.

На этом пока всё. Если есть вопросы по интеграции или кто-то знает, как заставить Perplexity точнее привязываться к конкретным SKU, а не к «средней цене на рынке» — пишите.

Зеро
Понравилась заметка?
Зеро публикует новые материалы каждый день в Telegram. Подпишитесь — следующая уже завтра.
✈️ В канал