Amazon, один из крупнейших публичных каталогов товарных данных в сети. Каждая страница товара содержит название, цену, звёздный рейтинг и статус наличия, а эти данные используются для отслеживания конкурентных цен, исследования рынка, анализа ассортимента и мониторинга спроса. Сохранить один товар вручную тривиально. Сохранить сотни или тысячи, вот где нужен парсер, и именно тут начинают давать о себе знать механизмы защиты Amazon.

Это руководство показывает, как парсить данные о товарах Amazon на Ruby. Вы создадите небольшой готовый к запуску скрипт, который получает отрендеренную страницу товара через Crawling API, разбирает её с помощью Nokogiri и формирует чистую запись: название товара, цену, рейтинг и наличие. Руководство ограничивается публичными данными о товарах, а юридический раздел ближе к концу, не формальность, поэтому прочтите его перед запуском на реальных объёмах.

Что вы создадите

Скрипт на Ruby, который принимает URL товара Amazon, получает страницу через Crawling API и извлекает структурированную запись с помощью Nokogiri. Из страницы товара извлекаются следующие поля:

  • Название наименование товара в заголовке страницы, например "Echo Dot (5th Gen)".
  • Цена указанная цена в блоке покупки.
  • Рейтинг средний звёздный рейтинг, если он есть у товара.
  • Наличие статус наличия на складе, например "In Stock" или "Currently unavailable".

Почему обычный запрос не работает на Amazon

Если запросить URL товара Amazon с помощью простого HTTP-клиента, вы редко получаете страницу, которую видит покупатель. Два фактора работают против вас. Во-первых, Amazon быстро помечает автоматизированный трафик: IP датацентров и паттерны запросов, не похожие на настоящий браузер, получают CAPTCHA, проверку на роботов или блокировку ещё до того, как достигают разметки товара. Во-вторых, части страницы рендерятся или изменяются в зависимости от региона посетителя, сессии и устройства, поэтому наивный запрос часто возвращает усечённую или непоследовательную версию объявления.

Поэтому работающий парсер Amazon требует IP, который платформа воспринимает как настоящего покупателя, и, там где страница зависит от рендеринга, браузера, который реально запускает страницу. Можно собрать это самостоятельно с пулом ротирующих резидентских прокси и headless-браузером, но сборка и поддержание этой связки составляет большую часть работы. Crawling API объединяет и то, и другое в одном вызове: вы отправляете ему URL, он получает страницу за доверенным резидентским IP и обрабатывает слой CAPTCHA, а возвращает готовый HTML для разбора.

Обычный токен против JS-токена

Crawlbase предлагает два типа токенов. Обычный токен получает HTML страницы и является правильным вариантом по умолчанию для страницы товара Amazon. JavaScript (JS) токен дополнительно рендерит страницу в реальном браузере, что стоит больше кредитов и стоит приберечь для содержимого, которое появляется только после выполнения клиентских скриптов. Начните с обычного токена и переходите на JS-токен только если нужное поле возвращается пустым.

Предварительные требования

Перед написанием кода нужно подготовить несколько вещей. Это не займёт много времени.

Базовые знания Ruby. Вы должны уметь писать и запускать скрипт на Ruby, а также устанавливать гемы. Если язык для вас нов, официальная документация Ruby и любой вводный курс доведут вас до уровня, который предполагает это руководство.

Ruby 2.7 или выше. Проверьте версию командой ruby --version. Если Ruby не установлен, скачайте его с ruby-lang.org или через менеджер версий, например rbenv или rvm.

Аккаунт Crawlbase и токен. Зарегистрируйтесь, откройте панель управления и скопируйте обычный токен запроса со страницы аккаунта. Обращайтесь с токеном как с паролем: он аутентифицирует ваши запросы, поэтому не включайте его в систему контроля версий. Crawlbase даёт 1 000 бесплатных запросов для старта без необходимости вводить карту, и вы платите только за успешные запросы после их исчерпания.

Настройка проекта

Создайте файл amazon_scraper.rb для кода, затем установите два гема, которые нужны парсеру: официальный клиент Crawlbase и Nokogiri для разбора.

bash
ruby --version

gem install crawlbase
gem install nokogiri

Две зависимости выполняют основную работу: crawlbase, официальный клиент Crawling API, а nokogiri разбирает возвращаемый HTML, позволяя извлекать каждое поле из страницы по CSS-селектору. Если предпочитаете Gemfile, добавьте gem 'crawlbase' и gem 'nokogiri' и выполните bundle install.

Понимание структуры страницы товара Amazon

Страница товара Amazon организует объявление в стабильные, легко идентифицируемые элементы. Название товара находится в заголовке с id productTitle. Цена отображается в блоке покупки, средний рейтинг, в сводке отзывов, а статус наличия, в блоке доступности. Разметка Amazon объёмная и варьируется по категориям, но эти основные поля имеют стабильные id и атрибуты, на которые можно ориентироваться.

Перед написанием селекторов откройте страницу товара в браузере, кликните правой кнопкой на заголовок или цену и выберите «Просмотр кода». Зафиксируйте id или класс каждого нужного поля. Amazon использует несколько форматов отображения цены в зависимости от типа акции, поэтому полезно проверить несколько товаров перед выбором селекторов. Id вроде #productTitle наиболее долговечны; основанные на классах ценовые span-элементы меняются чаще, поэтому планируйте их проверку по живой странице.

Шаг 1: Получить страницу товара

Начните с получения HTML страницы. Подключите гем Crawlbase, инициализируйте API с вашим токеном, укажите URL товара и запросите его. Проверяйте код статуса перед разбором, чтобы сбои были заметны, а не молчаливы.

ruby
require 'crawlbase'

api = Crawlbase::API.new(token: 'YOUR_CRAWLBASE_TOKEN')
url = 'https://www.amazon.com/dp/B09B8V1LZ3'

response = api.get(url)

if response.status_code == 200
  html = response.body
  puts html[0..500]
else
  puts "Request failed: #{response.status_code}"
end

Вызов Crawlbase::API.new создаёт клиент, привязанный к вашему токену, а api.get(url) получает страницу за доверенным IP. Ответ содержит status_code и body; проверка кода перед чтением тела означает, что блокировка или ошибка проявляется немедленно, а не порождает непонятный сбой при разборе. Запустите скрипт и вы должны увидеть реальную разметку товара Amazon в первых 500 символах, а не страницу с проверкой на робота. Это подтверждает работу получения данных до написания первого селектора.

Crawlbase Amazon Scraper

Единственный вызов api.get(url) делает сложную часть за вас. Amazon требует, чтобы запрос поступал с IP, воспринимаемого как настоящий покупатель, и проходил слой CAPTCHA за один раз. Crawling API получает страницу через ротирующие резидентские IP и обрабатывает проверки на ботов на стороне сервера, поэтому вам не нужно запускать собственный headless-браузерный флот и пул прокси. Сначала укажите URL товара на бесплатном тарифе.

Шаг 2: Разобрать поля с помощью Nokogiri

Имея HTML страницы, загрузите его в Nokogiri и извлеките каждое поле по его селектору. Amazon предоставляет доступ к названию через id #productTitle, к цене через ценовой span в блоке покупки, к рейтингу через сводку отзывов, а к статусу наличия через блок доступности. Небольшая вспомогательная функция, возвращающая nil при отсутствии элемента, предотвращает сбой при отсутствии поля в конкретном объявлении.

ruby
require 'nokogiri'

def text_at(doc, selector)
  node = doc.at_css(selector)
  node ? node.text.strip : nil
end

def parse_product(html)
  doc = Nokogiri::HTML(html)

  title = text_at(doc, '#productTitle')
  price = text_at(doc, '.a-price .a-offscreen')
  rating = text_at(doc, '#acrPopover .a-icon-alt')
  availability = text_at(doc, '#availability')

  {
    title: title,
    price: price,
    rating: rating,
    availability: availability
  }
end

Вспомогательная функция text_at запрашивает один элемент и возвращает его обрезанный текст или nil при отсутствии элемента, поэтому отсутствующее поле никогда не вызывает исключение при вызове .text на несуществующем объекте. Для цены .a-price .a-offscreen нацелена на версию цены для скринридеров, которая является наиболее согласованным единственным значением в различных форматах отображения цен Amazon. Рейтинг считывается из текста подсказки #acrPopover (строка вида "4.6 out of 5 stars"), а наличие берётся из блока #availability. В прежних версиях этого руководства использовался старый id #priceblock_ourprice; Amazon перешёл на структуру .a-price, поэтому проверка селекторов по живой странице важна.

Селекторы устаревают

Amazon использует несколько форматов отображения цены и наличия в зависимости от товара, типа акции и региона, и со временем меняет имена классов. Воспринимайте приведённые выше селекторы как отправную точку, а не как контракт. Если поле возвращает nil, откройте живую страницу товара в инструментах разработчика браузера, найдите текущий id или класс и обновите селектор. Периодическое обновление селекторов, норма для любого производственного парсера, а не признак поломки.

Шаг 3: Собрать всё вместе

Теперь свяжите получение данных и разбор в один готовый к запуску скрипт. Получите страницу товара, передайте HTML парсеру и выведите структурированную запись.

ruby
require 'crawlbase'
require 'nokogiri'

api = Crawlbase::API.new(token: 'YOUR_CRAWLBASE_TOKEN')

def text_at(doc, selector)
  node = doc.at_css(selector)
  node ? node.text.strip : nil
end

def parse_product(html)
  doc = Nokogiri::HTML(html)
  {
    title: text_at(doc, '#productTitle'),
    price: text_at(doc, '.a-price .a-offscreen'),
    rating: text_at(doc, '#acrPopover .a-icon-alt'),
    availability: text_at(doc, '#availability')
  }
end

url = 'https://www.amazon.com/dp/B09B8V1LZ3'
response = api.get(url)

if response.status_code == 200
  product = parse_product(response.body)
  product[:url] = url
  puts JSON.pretty_generate(product)
else
  puts "Request failed: #{response.status_code}"
end

Это полный парсер. Он подключает два гема, создаёт клиент, получает страницу, разбирает четыре поля и выводит их. JSON.pretty_generate входит в стандартную библиотеку Ruby, поэтому добавьте require 'json' в начало, если ваше окружение не загружает его автоматически. Замените url на любой товар Amazon, и тот же парсер справится с ним, поскольку селекторы полей основаны на структуре страницы, а не на конкретном товаре.

Как выглядит результат

Запустите скрипт командой ruby amazon_scraper.rb и получите чистую запись, готовую к записи в JSON, CSV или базу данных.

json
{
  "title": "Echo Dot (5th Gen, 2022 release) | Smart speaker with Alexa | Charcoal",
  "price": "$49.99",
  "rating": "4.7 out of 5 stars",
  "availability": "In Stock",
  "url": "https://www.amazon.com/dp/B09B8V1LZ3"
}

Отсюда вы можете сохранить запись, добавить её в CSV или передать в дашборд ценообразования. Поскольку парсер возвращает обычный хеш Ruby, запись в любой формат, это однострочник со стандартной библиотекой.

Масштабирование на множество товаров

Один товар, это демонстрация; реальная задача охватывает список товаров. Самый чистый способ масштабирования, хранить URL в массиве, итерироваться по ним и собирать каждую разобранную запись. Короткая пауза между запросами задаёт темп, чтобы не нагружать Amazon в плотном цикле.

ruby
urls = [
  'https://www.amazon.com/dp/B09B8V1LZ3',
  'https://www.amazon.com/dp/B07FZ8S74R',
  'https://www.amazon.com/dp/B08N5WRWNW'
]

results = []

urls.each do |url|
  response = api.get(url)
  next unless response.status_code == 200

  product = parse_product(response.body)
  product[:url] = url
  results << product
  puts "Scraped: #{product[:title]}"

  sleep 2
end

puts JSON.pretty_generate(results)

Защита next unless пропускает любой URL, не вернувший чистый 200, чтобы один плохой ответ не остановил выполнение, а sleep 2 между запросами поддерживает разумный темп. Если у вас тысячи URL и вы хотите обрабатывать их параллельно без управления собственной очередью, асинхронный Crawler создан именно для этого. Для первоначального сбора URL товаров смотрите сопутствующее руководство парсинг данных о товарах Amazon и обзор парсинга в e-commerce.

Как оставаться незаблокированным

Даже при надёжном IP, обрабатывающем получение данных, Amazon отслеживает трафик, характерный для парсеров. Несколько привычек поддерживают работоспособность сессии и применимы к любой хорошо защищённой коммерческой цели.

  • Регулируйте темп запросов. Распределяйте запросы с задержкой между товарами вместо обхода списка на полной скорости. sleep 2 в цикле, это минимум, а не максимум.
  • Полагайтесь на ротацию. Пул резидентских IP распределяет запросы по множеству реальных пользовательских адресов, чтобы ни один не превысил лимит скорости. Crawling API управляет этим за вас; если вы строите свой стек, именно эту часть нужно реализовать правильно.
  • Читайте коды статусов. Если сессия начинает возвращать вызовы или ошибки, это сигнал о том, что текущий темп или уровень IP недостаточен. Воспринимайте это как сигнал к снижению активности, а не как шум, который нужно игнорировать.

Более широкий план действий описан в как парсить сайты без блокировок. Если вы предпочитаете работать на другом языке, руководство веб-скрапинг с Java описывает тот же подход с другим инструментарием.

Законен ли парсинг Amazon?

Допустимость парсинга Amazon зависит от условий использования Amazon, вашей юрисдикции и того, что вы делаете с данными. Условия использования Amazon ограничивают автоматизированный доступ, поэтому парсинг может нарушать эти условия независимо от тщательности вашего инструментария. Ни один из приведённых здесь примеров кода этого не меняет; он просто обеспечивает работу технической части. Ознакомьтесь с условиями использования Amazon и его robots.txt и воспринимайте оба документа как границу того, что вы собираете.

Несколько принципов, которых стоит придерживаться. Собирайте только публичные данные: названия товаров, цены, рейтинги и статус наличия, которые любой может видеть на странице товара без аккаунта. Уважайте ожидаемые лимиты скорости Amazon и поддерживайте объём запросов достаточно низким, чтобы не перегружать серверы. Избегайте персональных данных, включая всё, связанное с идентифицируемыми покупателями, рецензентами или продавцами помимо публично указанного, и не распространяйте охраняемые авторским правом материалы, такие как изображения товаров или текст отзывов, выдавая их за свои. Если вы планируете коммерческое повторное использование данных, получите разрешение или официальное соглашение, а не исходите из того, что молчание означает согласие.

Это руководство намеренно ограничено публичными страницами товаров, поскольку именно это позволяет работе оставаться защищаемой. Оно не охватывает данные за логином, данные аккаунтов или заказов, платёжные процессы или оформление заказов, а также любые попытки обойти аутентификацию. Для лицензированного или массового доступа Amazon предлагает официальные API через программы Product Advertising и Selling Partner, и это правильный инструмент при необходимости больших объёмов, гарантированной структуры или коммерческих прав. Если вашему проекту нужно больше, чем публичные объявления, официальный API или соглашение на данные, правильный путь, а не более хитрый парсер.

Итоги

Ключевые выводы

  • Amazon блокирует наивные запросы. Простой HTTP-клиент получает CAPTCHA и проверки на робота, поэтому нужен запрос, поступающий с доверенного IP и проходящий эти защитные уровни.
  • Crawling API берёт на себя сложную часть. Один вызов api.get(url) получает страницу через ротирующие резидентские IP и слой CAPTCHA, избавляя от необходимости запускать собственный пул прокси и флот браузеров.
  • Nokogiri выполняет извлечение. Загрузите HTML и сопоставьте название, цену, рейтинг и наличие с текущими селекторами, такими как #productTitle и .a-price .a-offscreen, и ожидайте их устаревания.
  • Масштабируйтесь циклом с задержкой. Итерируйтесь по списку URL товаров, проверяйте код статуса, задавайте темп с помощью sleep и переходите к асинхронному Crawler при больших объёмах.
  • Оставайтесь в рамках публичных данных. Соблюдайте условия использования Amazon и robots.txt, для лицензированных или массовых данных используйте официальный API Amazon, и никогда не касайтесь аккаунтов, заказов или персональных данных.

Часто задаваемые вопросы

Почему обычный запрос на Ruby не работает на Amazon?

Amazon быстро помечает автоматизированный трафик. Обычный запрос с использованием Net::HTTP или open-uri с IP датацентра обычно получает CAPTCHA, страницу проверки на робота или прямую блокировку вместо разметки товара. Чтобы получить реальные данные, нужен запрос, поступающий с IP, воспринимаемого Amazon как настоящий покупатель, и проходящий проверки на ботов, именно это делает за вас Crawling API.

Нужен ли для Amazon обычный токен или JS-токен?

Начинайте с обычного токена. Для стандартной страницы товара Amazon обычный токен возвращает необходимые название, цену, рейтинг и наличие, и стоит меньше кредитов. Переходите на JavaScript (JS) токен только если конкретное нужное поле рендерится на стороне клиента и возвращается пустым при обычном токене.

Какие селекторы использовать для цены?

Используйте .a-price .a-offscreen, нацеленный на версию цены для скринридеров и являющийся наиболее согласованным единственным значением в различных форматах отображения цен Amazon. Старый id #priceblock_ourprice из прошлых руководств больше не подходит для большинства страниц. Поскольку Amazon использует несколько форматов отображения цены, проверяйте селектор по живой странице товара перед масштабным запуском.

Как парсить много товаров Amazon одновременно?

Храните URL товаров в массиве, итерируйтесь по ним, разбирайте каждую страницу той же функцией и собирайте записи. Проверяйте код статуса, чтобы один плохой ответ не остановил выполнение, и добавляйте короткий sleep между запросами для задания темпа. При тысячах URL асинхронный Crawler обрабатывает их параллельно без необходимости управлять очередью самостоятельно.

Можно ли парсить данные заказов, аккаунтов или Buy Box с Amazon?

Это руководство не охватывает данные за логином. История заказов, данные аккаунтов и процессы оформления защищены аутентификацией, поэтому они не являются публичными данными, и их парсинг или обход логина нарушает условия Amazon. Для санкционированного доступа к более богатым данным правильный путь, официальный API Amazon или партнёрское соглашение.

Почему использовать Nokogiri вместо регулярных выражений для разбора HTML?

Nokogiri разбирает страницу в правильную DOM-структуру, позволяя выбирать поля по CSS-селектору или XPath и получать надёжные результаты даже при изменении окружающей разметки. Регулярные выражения по HTML ломаются в момент, когда Amazon переставляет атрибуты или вкладывает элемент иначе. Для любого реального парсера библиотека вроде Nokogiri одновременно надёжнее и проще в обслуживании.

Начать создавать

Обходите любой сайт в масштабе, без борьбы с инфраструктурой.

Crawlbase берёт на себя прокси, отпечатки и CAPTCHA, чтобы ваша команда выпускала конвейеры данных вместо поддержки обвязки краулинга. 1 000 запросов бесплатно, без карты.

Самообслуживание · Звонок отдела продаж не требуется · Доступны корпоративные объёмы краулинга