Маркетплейс Ozon стал ключевой площадкой для онлайн-торговли в России, но ручной сбор данных о товарах, ценах или отзывах конкурентов занимает часы. Автоматизация через парсинг на PHP позволяет анализировать тысячи позиций за минуты — если знать, как обойти ограничения платформы. В этой статье разберём легальные и технические аспекты парсинга Ozon, от официального API до обхода Cloudflare, с готовыми примерами кода.
Важно понимать: Ozon активно борется с автоматизированным сбором данных. Использование "грязных" методов (например, имитация кликов через curl без заголовков) приведёт к блокировке IP или аккаунта. Мы сосредоточимся на белых и серых методах, которые минимизируют риски: от работы с открытым API до ротации прокси и эмуляции поведения пользователя. Если вам нужны данные для анализа ниши, мониторинга цен или интеграции с CRM — этот гайд поможет избежать типичных ошибок.
Почему PHP для парсинга Ozon: плюсы и минусы языка
PHP остаётся одним из самых популярных языков для парсинга благодаря простоте интеграции с веб-протоколами и богатой экосистеме библиотек. Вот почему его выбирают для работы с Ozon:
- 🔹 Встроенные функции для HTTP-запросов:
file_get_contents(),curlиstream_contextпозволяют отправлять запросы без внешних зависимостей. - 🔹 Библиотеки для парсинга: Guzzle (для HTTP), Symfony DomCrawler (для разбора HTML), PHP Simple HTML DOM Parser.
- 🔹 Лёгкая интеграция с базами данных: данные с Ozon можно сразу сохранять в MySQL или PostgreSQL для дальнейшего анализа.
- 🔹 Хостинг-френдли: большинство shared-хостингов поддерживают PHP, в отличие от Python или Node.js.
Однако у PHP есть и недостатки:
- ⚠️ Низкая скорость выполнения по сравнению с Python (особенно при мультипоточности). Для парсинга тысяч страниц может потребоваться оптимизация.
- ⚠️ Сложности с асинхронностью: в отличие от Node.js, PHP не предназначен для параллельных запросов "из коробки" (решается библиотеками вроде ReactPHP).
- ⚠️ Ограничения хостинга: на дешёвых тарифах могут блокировать длительные скрипты или ограничивать количество запросов.
Для парсинга Ozon на PHP критично понимать, что 90% блокировок происходят не из-за языка, а из-за неправильных заголовков, отсутствия ротации IP или игнорирования robots.txt. Далее разберём, как это избежать.
Официальное API Ozon: легальный способ получить данные
Ozon предоставляет публичное API для продавцов и партнёров, которое позволяет получать данные о товарах, заказах, отзывах и аналитике без риска блокировки. Это единственный 100% легальный способ автоматизированного сбора информации, но с ограничениями:
- 🔑 Требуется авторизация: нужен
Client-IDиAPI-Key, которые выдаются после регистрации в Ozon Seller. - 📊 Ограничения по запросам: например, для метода
/v2/product/infoлимит — 60 запросов в минуту. - 📦 Не все данные доступны: API не вернёт HTML-код страниц товаров или динамически подгружаемые отзывы.
Пример запроса к API на PHP с использованием Guzzle:
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://api-seller.ozon.ru/',
'headers' => [
'Client-Id' => 'ВАШ_CLIENT_ID',
'Api-Key' => 'ВАШ_API_KEY',
'Content-Type' => 'application/json',
]
]);
$response = $client->get('/v2/product/info', [
'query' => [
'product_id' => 12345678, // ID товара
'offer_id' => ''
]
]);
$data = json_decode($response->getBody(), true);
print_r($data);
?
Для работы с API Ozon рекомендуем:
- Использовать официальную документацию — методы часто обновляются.
- Кэшировать ответы, чтобы не превышать лимиты запросов.
- Для аналитики использовать
/v1/analytics/data— он возвращает данные по продажам, трафику и конверсиям.
⚠️ Внимание: Если вы парсите данные для конкурентного анализа (например, цены других продавцов), API может вернуть неполную информацию. В этом случае придётся комбинировать его с другими методами.
☑️ Подготовка к работе с API Ozon
Парсинг HTML-страниц Ozon: обход защиты и ротация прокси
Если API не подходит (например, нужны отзывы или динамически подгружаемый контент), придётся парсить HTML-страницы. Ozon использует несколько уровней защиты:
- 🛡️ Cloudflare: проверяет запросы на "ботоподобность" (отсутствие заголовков, нетипичный
User-Agent). - 🔍 JavaScript-рендеринг: часть контента (например, отзывы) подгружается динамически через React.
- 🚫 Блокировка по IP: при большом количестве запросов с одного адреса.
Чтобы обойти защиту, нужен комплексный подход:
- Имитация браузера: используйте реальные заголовки (например, из Chrome DevTools). Пример:
$headers = [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept-Language' => 'ru-RU,ru;q=0.9',
'Referer' => 'https://www.ozon.ru/',
'Sec-Ch-Ua-Platform' => '"Windows"',
];
- Ротация прокси: используйте платные прокси (например, Luminati или Smartproxy) с геолокацией "Россия".
- Задержки между запросами: имитируйте поведение пользователя (2–5 секунд между страницами).
- Обработка JavaScript: для динамического контента понадобится headless-браузер (например, Puppeteer через Node.js или Selenium).
Пример скрипта для парсинга страницы товара с ротацией прокси:
<?php
$proxies = [
'http://login:password@proxy1.example.com:8080',
'http://login:password@proxy2.example.com:8080',
];
$proxy = $proxies[array_rand($proxies)];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.ozon.ru/product/tokarnyy-stanok-12345678/');
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$html = curl_exec($ch);
curl_close($ch);
// Далее парсим $html с помощью DomCrawler или regex
⚠️ Внимание: Ozon может блокировать даже легальные прокси, если они используются многими парсерами. Тестируйте новые IP перед массовым сбором данных.
Как проверить, что ваш скрипт не заблокирован?
Откройте страницу https://www.ozon.ru/ в браузере и через DevTools (F12) проверьте заголовок ответа. Если там есть "CF-RAY" или "cf-chl-bypass", значит Cloudflare активен. Сравните заголовки вашего скрипта с браузерными.
Парсинг цен и наличия товаров: пример на PHP + Guzzle
Одна из самых востребованных задач — мониторинг цен конкурентов. Для этого нужно парсить страницы товаров и извлекать данные из HTML. Рассмотрим пример с использованием Guzzle и Symfony DomCrawler:
Установите зависимости:
composer require guzzlehttp/guzzle symfony/dom-crawler symfony/css-selector
Код для извлечения цены и наличия:
<?php
use GuzzleHttp\Client;
use Symfony\Component\DomCrawler\Crawler;
$client = new Client([
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
'Accept' => 'text/html,application/xhtml+xml,...',
]
]);
$response = $client->get('https://www.ozon.ru/product/iphone-15-pro-12345678/');
$html = $response->getBody()->getContents();
$crawler = new Crawler($html);
// Цена (может отличаться в зависимости от структуры страницы)
$price = $crawler->filter('.c1a .tsBody500')->text();
$price = preg_replace('/[^0-9]/', '', $price); // Очищаем от символов
// Наличие
$availability = $crawler->filter('.a4c5')->text();
echo "Цена: " . $price . " руб.\n";
echo "Наличие: " . trim($availability);
Обратите внимание:
- 🔍 Селекторы (
.c1a .tsBody500) могут меняться — проверяйте их актуальность через DevTools (Ctrl+Shift+C). - 📦 Для товаров с вариантами (цвет, размер) нужно парсить JSON из
<script type="application/ld+json">. - 💰 Цены в Ozon могут динамически меняться (акции, скидки). Для точного мониторинга нужен регулярный опрос (например, раз в час).
| Данные | Селектор (пример) | Примечания |
|---|---|---|
| Цена | .c1a .tsBody500 |
Может быть несколько цен (со скидкой, без скидки). |
| Наличие | .a4c5 |
Текст типа "В наличии" или "Под заказ". |
| Название товара | h1.tsBody500 |
Иногда содержит артикул. |
| Рейтинг | [data-widget="webRating"] |
Данные могут подгружаться динамически. |
Парсинг отзывов: как обойти динамическую подгрузку
Отзывы на Ozon подгружаются динамически через React, поэтому обычный парсинг HTML не сработает. Есть три способа получить их:
- Через API отзывов (если есть доступ к Ozon Seller API).
- Парсинг XHR-запросов: отзывы подгружаются по адресу
https://www.ozon.ru/api/comments/v2/c1/comments.... - Использование headless-браузера (например, Puppeteer), если первые два метода не работают.
Пример парсинга XHR-запроса на PHP:
<?php
$productId = 12345678; // ID товара
$url = "https://www.ozon.ru/api/comments/v2/c1/comments?productId=$productId&page=1&pageSize=10";
$client = new Client([
'headers' => [
'User-Agent' => 'Mozilla/5.0 ...',
'Accept' => 'application/json',
'Referer' => "https://www.ozon.ru/product/tovar-$productId/",
]
]);
$response = $client->get($url);
$data = json_decode($response->getBody(), true);
// Сохраняем отзывы в массив
$reviews = $data['comments'];
foreach ($reviews as $review) {
echo "Рейтинг: {$review['rating']}\n";
echo "Текст: {$review['text']}\n";
echo "Дата: {$review['createdTime']}\n\n";
}
Сложности при парсинге отзывов:
- 🔄 Пагинация: отзывы подгружаются порциями (обычно по 10 штук). Нужно итерировать по страницам (
page=1,page=2и т.д.). - 🛡️ Защита Cloudflare: XHR-запросы тоже могут блокироваться. Используйте те же заголовки, что и для основной страницы.
- 📅 Ограничение по дате: старые отзывы могут не подгружаться. Для анализа нужно собирать данные регулярно.
⚠️ Внимание: Парсинг отзывов в больших объёмах может быть расценен как нарушение пользовательского соглашения Ozon. Используйте эти данные только для личного анализа, не публикуйте их открыто.
Автоматизация и сохранение данных: от парсинга к аналитике
Собранные данные бесполезны, если их не структурировать и не анализировать. Рассмотрим, как автоматизировать процесс:
- Сохранение в базу данных:
<?php$pdo = new PDO('mysql:host=localhost;dbname=ozon_data', 'user', 'pass');
$stmt = $pdo->prepare("INSERT INTO products (id, price, availability) VALUES (?, ?, ?)");
$stmt->execute([$productId, $price, $availability]);
- Экспорт в CSV/Excel:
file_put_contents("products.csv", "$productId;$price;$availability\n", FILE_APPEND); - Интеграция с Google Sheets через API или библиотеку Google APIs Client.
- Отправка уведомлений (например, если цена изменилась):
mail("admin@example.com", "Цена изменилась!", "Товар $productId: старая цена $oldPrice, новая $price");
Пример структуры базы данных для хранения данных с Ozon:
| Поле | Тип | Описание |
|---|---|---|
product_id |
INT | ID товара на Ozon |
price |
DECIMAL(10,2) | Текущая цена |
old_price |
DECIMAL(10,2) | Предыдущая цена (для отслеживания изменений) |
availability |
VARCHAR(50) | Наличие ("В наличии", "Под заказ" и т.д.) |
last_updated |
DATETIME | Время последнего обновления |
Для автоматизации запуска парсера используйте cron (на Linux) или Планировщик задач (на Windows). Пример задачи для cron, которая запускает скрипт каждый час:
0 /usr/bin/php /path/to/your/parser.php > /dev/null 2>&1
Юридические риски и как их избежать
Парсинг данных с Ozon находится в "серой зоне" с юридической точки зрения. Согласно пользовательскому соглашению, автоматизированный сбор данных без разрешения запрещён. Однако на практике:
- ✅ Разрешено:
- Использование официального API в рамках лимитов.
- Сбор данных для личного использования (например, анализ конкурентов для своего магазина).
- Парсинг публично доступной информации (цены, описания товаров).
- ❌ Запрещено:
- Массовый сбор данных для перепродажи (например, создание базы email покупателей).
- Обход защиты, который нагружает серверы Ozon (DDOS-атаки).
- Публикация парсинговых данных в открытом доступе (например, на своём сайте).
Как минимизировать риски:
- Используйте официальное API везде, где это возможно.
- Ограничивайте частоту запросов (не более 1 запроса в 5–10 секунд с одного IP).
- Не сохраняйте персональные данные пользователей (имена, email из отзывов).
- Если вас заблокировали — не пытайтесь обойти блокировку с того же IP/аккаунта. Лучше напишите в поддержку Ozon с объяснением целей парсинга.
⚠️ Внимание: В 2023 году Ozon подал несколько исков против сервисов, занимающихся массовым парсингом данных для перепродажи. Если вы используете собранную информацию в коммерческих целях, проконсультируйтесь с юристом.
FAQ: Частые вопросы по парсингу Ozon на PHP
Можно ли парсить Ozon без прокси?
Технически да, но только для небольших объёмов (например, 10–20 запросов в день). При большем количестве ваш IP будет заблокирован. Для стабильной работы используйте ротацию прокси (например, через ProxyMesh или Luminati).
Как обновить селекторы, если Ozon изменил структуру страницы?
Откройте нужную страницу в браузере, нажмите F12 (DevTools), затем Ctrl+Shift+C и выделите нужный элемент. Скопируйте селектор (правой кнопкой → Copy → Copy selector). Для динамического контента ищите XHR-запросы во вкладке Network.
Что делать, если Cloudflare блокирует все запросы?
Попробуйте следующее:
- Обновите
User-Agentдо актуальной версии браузера. - Добавьте заголовки
Sec-Ch-Ua,Sec-Ch-Ua-Mobile,Sec-Ch-Ua-Platform. - Используйте резидентные прокси (например, Bright Data).
- Если ничего не помогает — переходите на headless-браузеры (например, Puppeteer).
Как парсить товары по категориям, а не по ID?
Для парсинга категорий нужно:
- Найти URL категории (например,
https://www.ozon.ru/category/smartfony-15502/). - Спарсить ссылки на товары с страницы категории (селектор:
a.tile-hover-target). - Далее парсить каждую ссылку отдельно (с задержками!).
Обратите внимание: категории на Ozon часто имеют пагинацию (например, ?page=2), и товары подгружаются динамически.
Можно ли парсить Ozon с хостинга, а не с локального сервера?
Да, но учитывайте:
- 🔹 На shared-хостингах могут блокировать
curlили длительные скрипты. - 🔹 IP хостинга может быть уже в чёрном списке Ozon.
- 🔹 Для парсинга лучше использовать VPS (например, Selectel или Timeweb Cloud) с российским IP.