Назад к статьям

Парсинг Ozon: мониторинг цен и товаров

Привет! Ozon — это второй по популярности маркетплейс в России после Wildberries. И парсить его тоже можно! Правда, структура немного другая, но мы справимся. 🛍️

Как работает Ozon API?

Ozon использует внутренний API для загрузки данных. К счастью, он достаточно открытый и не требует авторизации для базовых запросов. Главное — правильно сформировать запросы.

Поиск товаров

Начнём с поиска товаров по запросу:

import requests import json def search_ozon(query, page=1): """Поиск товаров на Ozon""" url = "https://www.ozon.ru/api/composer-api.bx/page/json/v2" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept': 'application/json', 'Referer': 'https://www.ozon.ru/' } params = { 'url': f'/search/?text={query}&page={page}' } response = requests.get(url, headers=headers, params=params) if response.status_code == 200: data = response.json() # Структура ответа может меняться, нужно адаптировать return data return None # Использование results = search_ozon('ноутбук', page=1)

Альтернативный способ: парсинг HTML

Иногда проще парсить HTML напрямую, особенно если API недоступен:

from bs4 import BeautifulSoup import requests def parse_ozon_search(query): """Парсим результаты поиска Ozon через HTML""" url = f"https://www.ozon.ru/search/?text={query}" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept': 'text/html,application/xhtml+xml' } response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') products = [] # Ищем карточки товаров (селектор может меняться!) product_cards = soup.find_all('div', {'data-widget': 'searchResultsV2'}) for card in product_cards: try: name = card.find('span', class_='tsBodyL').text price = card.find('span', class_='tsHeadline500').text link = card.find('a')['href'] products.append({ 'name': name, 'price': price, 'link': f"https://www.ozon.ru{link}" }) except: continue return products # Использование products = parse_ozon_search('смартфон') for product in products: print(f"{product['name']}: {product['price']}")

Получаем информацию о товаре

Для получения детальной информации о товаре нужен его ID:

def get_product_info(product_id): """Получаем детальную информацию о товаре""" url = f"https://www.ozon.ru/product/{product_id}" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') # Извлекаем данные (селекторы могут меняться!) try: name = soup.find('h1').text price = soup.find('span', {'data-test-id': 'price'}).text rating = soup.find('span', class_='rating').text reviews_count = soup.find('span', class_='reviews-count').text return { 'name': name, 'price': price, 'rating': rating, 'reviews': reviews_count } except: return None # Использование info = get_product_info(12345678) print(json.dumps(info, ensure_ascii=False, indent=2))

Мониторинг цен

Создадим систему мониторинга цен:

import json from datetime import datetime import time def monitor_ozon_price(product_id, check_interval=3600): """Мониторинг цены товара на Ozon""" price_history = [] while True: info = get_product_info(product_id) if info: current_price = info['price'] timestamp = datetime.now().isoformat() price_history.append({ 'timestamp': timestamp, 'price': current_price }) # Сохраняем историю with open(f'ozon_price_{product_id}.json', 'w') as f: json.dump(price_history, f, ensure_ascii=False, indent=2) print(f"[{timestamp}] Цена: {current_price}") time.sleep(check_interval)

Парсим отзывы

Отзывы тоже можно парсить, хотя это сложнее:

def get_product_reviews(product_id, page=1): """Получаем отзывы о товаре""" url = f"https://www.ozon.ru/product/{product_id}/reviews" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } params = { 'page': page } response = requests.get(url, headers=headers, params=params) soup = BeautifulSoup(response.text, 'html.parser') reviews = [] # Ищем отзывы (селектор может меняться!) review_items = soup.find_all('div', class_='review-item') for item in review_items: try: rating = item.find('span', class_='rating').text text = item.find('div', class_='review-text').text author = item.find('span', class_='author').text reviews.append({ 'rating': rating, 'text': text, 'author': author }) except: continue return reviews

Важные моменты

  • Селекторы меняются: Ozon часто обновляет структуру HTML, поэтому селекторы могут перестать работать.
  • Задержки: Не делай слишком много запросов — добавь задержки между ними.
  • User-Agent: Всегда используй правильный User-Agent.

Итоги

Парсинг Ozon требует больше усилий, чем Wildberries, но это вполне реально. Главное — быть готовым к изменениям в структуре сайта и адаптировать код. Удачи! 💪