Привет! 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, но это вполне реально. Главное — быть готовым к изменениям в структуре сайта и адаптировать код. Удачи! 💪