Страницы Amazon «Бестселлеры» представляют собой актуальный публичный рейтинг того, что реально продаётся в каталоге. Каждая категория, от электроники до компьютеров и аксессуаров, имеет собственный упорядоченный список лучших продуктов, обновляемый Amazon ежечасно, где прямо на странице указываются ранг, название, цена и рейтинг каждого товара. Этот рейтинг является одним из самых чистых сигналов о спросе в открытом вебе, поэтому исследователи продуктов, продавцы и аналитики отслеживают его для выявления тенденций, конкурентного анализа и ценовых решений.
Это руководство показывает, как парсить список Amazon «Бестселлеры» на Python. Вы создадите небольшой рабочий скрапер, который получает страницу «Бестселлеров» категории через Crawling API, парсит чистую запись для каждого ранжированного продукта и экспортирует результаты в JSON и CSV. Руководство намеренно ограничено публичными данными рейтинга: названиями, ценами, рейтингами и ссылками, которые любой желающий может видеть на странице «Бестселлеров» без входа в систему.
Что вы создадите
Скрипт на Python, который принимает URL категории Amazon «Бестселлеры», получает отрисованную страницу через Crawling API и извлекает структурированную запись для каждого ранжированного продукта. В качестве рабочего примера мы используем страницу «Бестселлеры в категории "Компьютеры и аксессуары"» и извлекаем следующие поля из каждой ранжированной карточки:
- Ранг позиция продукта в списке, например 1 для лучшего продавца.
- Название название продукта, отображаемое в карточке рейтинга.
- Цена указанная цена, если продукт её показывает.
- Рейтинг средний звёздный рейтинг, например "4.7 out of 5 stars".
- Ссылка URL на собственную страницу продукта.
Почему обычный запрос не работает на Amazon
Если направить простой HTTP-клиент на URL Amazon «Бестселлеры», вы редко получите искомый список. Против вас работают два фактора. Во-первых, значительная часть сетки рейтинга отрисовывается на стороне клиента: Amazon отправляет лёгкую оболочку и заполняет карточки по мере выполнения JavaScript страницы и прокрутки, поэтому начальный HTML часто не содержит позиции с низким рангом. Во-вторых, Amazon быстро помечает автоматизированный трафик. Диапазоны IP-адресов датацентров и паттерны запросов, которые не выглядят как настоящий браузер, сталкиваются с CAPTCHA, заглушкой «robot check» или прямой блокировкой ещё до попытки получить список.
Поэтому рабочий скрапер «Бестселлеров» требует двух вещей в одном запросе: браузера, который отрисовывает страницу, и IP-адреса, который Amazon воспринимает как настоящего покупателя. Можно собрать это самостоятельно, используя headless-браузер и пул ротируемых резидентных прокси, но поддержание этого стека в рабочем состоянии занимает большую часть работы. Crawling API объединяет обе задачи в один вызов: вы отправляете ему URL категории, он отрисовывает страницу за доверенным резидентным IP-адресом, обрабатывает ротацию и решение CAPTCHA и возвращает готовый HTML для парсинга.
Предварительные требования
Перед написанием кода необходимо подготовить несколько вещей. Это не займёт много времени.
Базовые знания Python. Вы должны уметь писать и запускать скрипты Python, а также устанавливать пакеты с помощью pip. Если вы новичок в языке, официальная документация Python или любой вводный курс охватывает уровень, который предполагается в этом руководстве.
Python 3.8 или выше. Проверьте свою версию командой python --version (или python3 --version). Если у вас её нет, установите с python.org и убедитесь, что Python находится в системном PATH.
Аккаунт Crawlbase и токен. Зарегистрируйтесь для получения бесплатного аккаунта, откройте панель управления и скопируйте токен со страницы документации аккаунта. Бесплатный тариф включает до 20 000 запросов без карты, чего вполне достаточно для создания и тестирования этого скрапера. Относитесь к токену как к паролю и не включайте его в систему контроля версий.
Настройка проекта
Создайте виртуальное окружение, чтобы зависимости проекта оставались изолированными, затем установите две библиотеки, необходимые скраперу. crawlbase является официальным клиентом для Crawling API, а beautifulsoup4 парсит возвращаемый HTML, позволяя извлекать каждое поле из ранжированных карточек по CSS-селектору.
python --version python -m venv amazon_env source amazon_env/bin/activate pip install crawlbase beautifulsoup4
В Windows активируйте окружение командой amazon_env\Scripts\activate вместо строки source. После установки обеих библиотек создайте файл скрипта, который строится в остальной части руководства:
touch amazon_best_sellers.py
Понимание страницы «Бестселлеры»
Каждая категория «Бестселлеров» Amazon располагается по стабильному URL /zgbs/. Например, список «Компьютеры и аксессуары» находится по адресу https://www.amazon.com/Best-Sellers-Computers-Accessories/zgbs/pc, а «Электроника» по адресу https://www.amazon.com/Best-Sellers-Electronics/zgbs/electronics. Страница представляет собой упорядоченную сетку ранжированных карточек, по одной на продукт, каждая из которых содержит одинаковый набор полей: значок ранга, название, цена, звёздный рейтинг и ссылка на страницу продукта.
Прежде чем писать селекторы, откройте страницу «Бестселлеров» в браузере, нажмите правой кнопкой мыши на ранжированную карточку и выберите «Просмотр кода». Amazon оборачивает каждый ранжированный элемент в контейнер с атрибутом id="gridItemRoot", показывает ранг в пронумерованном значке в верхней части карточки и выводит название, цену и рейтинг внутри этого контейнера. Именно эти элементы вы и таргетируете. Имена служебных классов Amazon часто меняются, поэтому там, где возможно, используйте более устойчивые структурные атрибуты, такие как id="gridItemRoot", а не хрупкую цепочку классов.
Шаг 1: получение отрисованной страницы «Бестселлеров»
Начните с получения готовой страницы. Импортируйте класс CrawlingAPI, инициализируйте его с вашим токеном, установите URL категории и запросите его. Проверка кода статуса перед парсингом делает ошибки явными, а не скрытыми.
from crawlbase import CrawlingAPI api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"}) def crawl(page_url): options = {"ajax_wait": "true", "page_wait": 4000} response = api.get(page_url, options) if response["status_code"] == 200: return response["body"].decode("latin1") print(f"Request failed: {response['status_code']}") return None if __name__ == "__main__": bestsellers_url = "https://www.amazon.com/Best-Sellers-Computers-Accessories/zgbs/pc" html = crawl(bestsellers_url) print(html[:500] if html else "No HTML returned")
Два параметра ожидания важны для списка, который заполняется по мере загрузки страницы. ajax_wait указывает API ждать завершения асинхронного контента, а page_wait удерживает фиксированное количество миллисекунд после загрузки, чтобы карточки с поздней отрисовкой появились до захвата страницы. Тело декодируется как latin1, поскольку страницы Amazon содержат символы, которые могут вызвать ошибку при строгом декодировании UTF-8. Запустите скрипт, и вы должны увидеть реальную разметку рейтинга, а не оболочку с проверкой ботов. Это подтверждает работоспособность рендеринга, прежде чем писать хоть один селектор.
Список «Бестселлеров» требует отрисованной страницы за доверенным IP-адресом в одном вызове. Crawling API принимает ваш токен, запускает страницу категории в настоящем браузере, ротирует резидентные IP-адреса на стороне сервера и обрабатывает решение CAPTCHA, а затем передаёт готовый HTML. Вам не нужно самостоятельно запускать headless-браузерный флот и пул прокси. Начните с URL категории /zgbs/ на бесплатном тарифе до 20 000 запросов.
Шаг 2: парсинг ранжированных карточек с помощью BeautifulSoup
Имея отрисованный HTML, загрузите его в BeautifulSoup, найдите каждую ранжированную карточку и извлеките каждое поле по его селектору. Amazon оборачивает каждый ранжированный элемент в контейнер для выбора, показывает ранг в пронумерованном значке и выводит название, цену и рейтинг внутри карточки. Читайте ссылку на продукт из якорного элемента карточки. Оборачивайте каждую карточку в блок try/except, чтобы одно некорректное объявление не прерывало выполнение.
from bs4 import BeautifulSoup BASE = "https://www.amazon.com" def text_of(card, selector): el = card.select_one(selector) return el.get_text(strip=True) if el else None def parse_link(card): a = card.select_one("a.a-link-normal[href]") if not a: return None href = a["href"] return href if href.startswith("http") else BASE + href def scrape_best_sellers(html): soup = BeautifulSoup(html, "html.parser") cards = soup.select("div#gridItemRoot") results = [] for card in cards: try: rank = text_of(card, "span.zg-bdg-text") results.append({ "rank": rank.lstrip("#") if rank else None, "title": text_of(card, "div._cDEzb_p13n-sc-css-line-clamp-3_g3dy1"), "price": text_of(card, "span._cDEzb_p13n-sc-price_3mJ9Z"), "rating": text_of(card, "span.a-icon-alt"), "link": parse_link(card), }) except Exception as e: print(f"Skipped a card: {e}") return results
Вспомогательная функция text_of запрашивает один элемент внутри карточки и возвращает None при его отсутствии вместо того, чтобы выбрасывать исключение при вызове .get_text() на пустом объекте. Это делает извлечение устойчивым при отсутствии поля, что часто встречается, поскольку не каждый ранжированный элемент показывает цену. Ранг берётся из пронумерованного значка (span.zg-bdg-text) с удалением ведущего символа # для хранения чистого числа. Строка рейтинга находится в скрытом span.a-icon-alt, который содержит текст "4.7 out of 5 stars", отображаемый Amazon за звёздным значком, а ссылка нормализуется до абсолютного URL, поскольку Amazon часто возвращает относительный href.
Имена служебных классов Amazon p13n-sc (зажим заголовка, диапазон цены) генерируются и меняются без предупреждения, тогда как структурные маркеры, такие как div#gridItemRoot и span.zg-bdg-text, более устойчивы. Относитесь к селекторам на основе классов выше как к начальному шаблону, а не к постоянному контракту. Когда поле возвращает None для каждой карточки, повторно осмотрите живую страницу «Бестселлеров» в инструментах разработчика браузера и обновите селектор. Периодическое обслуживание селекторов является нормой для любого производственного скрапера.
Шаг 3: сборка скрипта и экспорт JSON и CSV
Теперь свяжите получение данных и парсинг в один рабочий скрипт, затем запишите записи в JSON и CSV, чтобы их можно было загрузить в блокнот или таблицу. Получите отрисованную страницу категории, передайте её парсеру и выгрузите структурированные строки.
import csv import json from crawlbase import CrawlingAPI from bs4 import BeautifulSoup api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"}) BASE = "https://www.amazon.com" FIELDS = ["rank", "title", "price", "rating", "link"] def crawl(page_url): options = {"ajax_wait": "true", "page_wait": 4000} response = api.get(page_url, options) if response["status_code"] == 200: return response["body"].decode("latin1") print(f"Request failed: {response['status_code']}") return None def text_of(card, selector): el = card.select_one(selector) return el.get_text(strip=True) if el else None def parse_link(card): a = card.select_one("a.a-link-normal[href]") if not a: return None href = a["href"] return href if href.startswith("http") else BASE + href def scrape_best_sellers(html): soup = BeautifulSoup(html, "html.parser") cards = soup.select("div#gridItemRoot") results = [] for card in cards: try: rank = text_of(card, "span.zg-bdg-text") results.append({ "rank": rank.lstrip("#") if rank else None, "title": text_of(card, "div._cDEzb_p13n-sc-css-line-clamp-3_g3dy1"), "price": text_of(card, "span._cDEzb_p13n-sc-price_3mJ9Z"), "rating": text_of(card, "span.a-icon-alt"), "link": parse_link(card), }) except Exception as e: print(f"Skipped a card: {e}") return results def export(rows, name="amazon_best_sellers"): with open(f"{name}.json", "w", encoding="utf-8") as f: json.dump(rows, f, indent=2, ensure_ascii=False) with open(f"{name}.csv", "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=FIELDS) writer.writeheader() writer.writerows(rows) print(f"Saved {len(rows)} products to {name}.json and {name}.csv") def main(): url = "https://www.amazon.com/Best-Sellers-Computers-Accessories/zgbs/pc" html = crawl(url) if not html: return rows = scrape_best_sellers(html) export(rows) if __name__ == "__main__": main()
Запустите полный скрипт командой python amazon_best_sellers.py. Он получает отрисованную страницу категории, парсит одну строку на каждый ранжированный продукт и записывает как amazon_best_sellers.json, так и amazon_best_sellers.csv. Общий список FIELDS поддерживает порядок столбцов CSV в соответствии с ключами словаря, поэтому оба экспорта никогда не расходятся.
Как выглядит вывод
Вы получаете чистый список ранжированных записей в порядке списка, готовый для записи в JSON, CSV или базу данных.
[ { "rank": "1", "title": "Amazon Basics High-Speed HDMI Cable, 6 Feet", "price": "$6.99", "rating": "4.7 out of 5 stars", "link": "https://www.amazon.com/dp/B014I8SSD0" }, { "rank": "2", "title": "Apple AirTag", "price": "$24.99", "rating": "4.7 out of 5 stars", "link": "https://www.amazon.com/dp/B0D54JZTHY" } ]
Более быстрый путь: встроенный скрапер «Бестселлеров»
Написание собственных селекторов даёт полный контроль, но также означает их поддержку по мере изменения разметки Amazon. Если вы хотите избежать этого, Crawling API поставляется со встроенным скрапером amazon-best-sellers, который напрямую возвращает ранжированный список в виде структурированного JSON, без необходимости в BeautifulSoup. Вы передаёте опцию scraper и читаете разобранное body.
import json from crawlbase import CrawlingAPI api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"}) url = "https://www.amazon.com/Best-Sellers-Electronics/zgbs/electronics" response = api.get(url, {"scraper": "amazon-best-sellers"}) if response.get("status_code") == 200: data = json.loads(response["body"].decode("latin1")) result = data.get("body", {}) with open("amazon_best_sellers.json", "w", encoding="utf-8") as f: json.dump(result, f, indent=4, ensure_ascii=False) print("Scraper response saved to amazon_best_sellers.json") else: print(f"Request failed: {response.get('status_code', 0)}")
Разобранный ответ включает pageTitle, массив products (каждый с полями title, price, customerReview, customerReviewCount, asin, image, url и position), список связанных categories и блок pagination. Это самый быстрый способ получить поддерживаемый поток рейтингов; ручной парсер выше является правильным выбором, когда вам нужны поля, которые встроенный скрапер не возвращает, или когда вы хотите изучить структуру страницы. Scraper API, задокументированный в разделе автоматического парсинга веб-данных, использует тот же автоматический парсинг.
Масштабирование по категориям и страницам
Одна категория является демонстрацией; реальная исследовательская задача охватывает многие. Amazon предоставляет список «Бестселлеров» почти для каждого отдела и подкатегории, каждый по своему URL /zgbs/, и каждый список разбит на страницы (обычно топ-50 разделён на две страницы с параметром ?pg=2). Перебирайте набор URL категорий и соблюдайте темп запросов, чтобы не перегружать Amazon в плотном цикле.
import time CATEGORIES = { "computers": "https://www.amazon.com/Best-Sellers-Computers-Accessories/zgbs/pc", "electronics": "https://www.amazon.com/Best-Sellers-Electronics/zgbs/electronics", } def scrape_categories(categories): everything = {} for name, url in categories.items(): rows = [] for page in (1, 2): page_url = url if page == 1 else f"{url}?pg={page}" html = crawl(page_url) if not html: break found = scrape_best_sellers(html) if not found: break rows.extend(found) print(f"{name} page {page}: {len(found)} products") time.sleep(2) everything[name] = rows return everything
Прерывание при пустых результатах останавливает вас досрочно, когда категория исчерпывает страницы, а time.sleep(2) между запросами задаёт темп, чтобы вас не пометили за быстрый трафик. Привязка вывода по имени категории сохраняет каждый список отдельно, что и нужно при сравнении рейтингов по отделам. Для отслеживания тенденций со временем запускайте задачу по расписанию и проставляйте дату каждому экспорту, затем сравнивайте последовательные снимки, чтобы видеть, что поднялось или опустилось в списке.
Как оставаться незаблокированным
Даже при решённом вопросе с рендерингом Amazon следит за трафиком, характерным для скраперов. Несколько привычек помогают поддерживать работоспособность, и они применимы к любой сложной коммерческой цели.
- Соблюдайте темп запросов. Распределяйте запросы с задержкой между страницами и категориями, а не сканируйте всё на полной скорости. Планируйте более объёмные задачи в непиковые часы, чтобы снизить нагрузку на серверы Amazon.
- Полагайтесь на ротацию. Пул резидентных IP-адресов распределяет запросы по множеству реальных адресов пользователей, чтобы ни один из них не превысил лимит. Crawling API обрабатывает это за вас; если вы используете собственный стек, это именно та часть, которую нужно правильно реализовать.
- Сохраняйте только необходимое. Храните поля рейтинга, которые нужны вашему проекту, и удаляйте остальное. Периодически проверяйте селекторы, чтобы скрапер соответствовал изменениям разметки.
Для более широкого руководства по обходу блокировок см. как парсить сайты, не получая блокировку, а для понимания важности рендеринга здесь, как сканировать JavaScript-сайты. Если вы хотите углубиться в сторону BeautifulSoup, руководство по использованию BeautifulSoup в Python подробно охватывает библиотеку парсинга.
Законно ли парсить Amazon?
Разрешённость парсинга Amazon зависит от Условий использования Amazon, вашей юрисдикции и того, что вы делаете с данными. Условия использования Amazon ограничивают автоматизированный доступ, поэтому парсинг может противоречить этим условиям независимо от осторожности ваших инструментов. Ни один из кодов здесь не изменяет этого; он просто обеспечивает работу технической части. Прочитайте Условия использования Amazon и его robots.txt, и относитесь к обоим как к границам того, что вы собираете. Для коммерческого или конкурентного использования правовая картина становится более сложной, и консультация с юристом по вашему конкретному случаю является разумным шагом.
Несколько правил, которых стоит придерживаться. Собирайте только публичные данные: ранги, названия продуктов, цены, рейтинги и ссылки на объявления, которые любой желающий может видеть на странице «Бестселлеров» без учётной записи. Поддерживайте объём запросов достаточно низким, чтобы не создавать нагрузку на серверы Amazon, и избегайте персональных данных, включая всё, связанное с идентифицируемыми покупателями, рецензентами или продавцами за пределами публично перечисленного. Если вы планируете коммерческое переиспользование данных, запрашивайте разрешение или официальное соглашение, а не предполагайте, что молчание означает согласие.
Это руководство намеренно ограничено публичными страницами рейтинга «Бестселлеров», поскольку именно это делает работу оправданной. Оно не охватывает ничего за логином, данных аккаунтов или заказов, персональной информации или каких-либо попыток обойти аутентификацию или CAPTCHA, на которую вы не имеете права. Для лицензированного или массового доступа Amazon предлагает Product Advertising API и другие официальные программы, и это является правильным инструментом, когда вам нужны большие объёмы, гарантированная структура или коммерческие права. Если вашему проекту нужно больше, чем публичные данные рейтинга, официальный API или соглашение об данных являются правильным путём, а не более хитрый скрапер.
Ключевые выводы
-
«Бестселлеры», это актуальный сигнал о спросе. Страница
/zgbs/каждой категории ранжирует текущие лучшие продукты, поэтому она так полезна для исследования продуктов и отслеживания тенденций. - Нужны одновременно рендеринг и доверенный IP-адрес. Amazon заполняет сетку рейтинга на стороне клиента и блокирует ботовый трафик, поэтому Crawling API отрисовывает страницу за резидентным IP-адресом в одном вызове.
-
BeautifulSoup выполняет извлечение. Перебирайте карточки
div#gridItemRootи сопоставляйте ранг, название, цену, рейтинг и ссылку с текущими селекторами, ожидая, что эти селекторы будут меняться. -
Экспортируйте в JSON и CSV. Общий список полей синхронизирует оба файла; встроенный скрапер
amazon-best-sellersявляется менее требовательной в обслуживании альтернативой, когда вам нужен структурированный JSON напрямую. - Оставайтесь в рамках публичных данных. Соблюдайте Условия использования и robots.txt Amazon, предпочитайте официальный Product Advertising API для лицензированных или массовых данных и никогда не трогайте аккаунты, заказы или персональную информацию.
Часто задаваемые вопросы
Почему обычный запрос не возвращает «Бестселлеры» с Amazon?
Две причины. Amazon заполняет большую часть сетки рейтинга на стороне клиента по мере загрузки и прокрутки страницы, поэтому необработанный запрос часто получает оболочку без позиций с низким рангом. Кроме того, Amazon бросает вызов трафику, который не выглядит как настоящий браузер, или блокирует его. Отрисовка страницы через Crawling API за доверенным IP-адресом решает обе проблемы, поэтому скрапер здесь маршрутизирует запрос через него.
Как парсить «Бестселлеры» для конкретной категории?
Каждый список «Бестселлеров» имеет собственный стабильный URL /zgbs/, например /Best-Sellers-Computers-Accessories/zgbs/pc для «Компьютеров и аксессуаров» или /Best-Sellers-Electronics/zgbs/electronics для «Электроники». Направьте скрапер на нужный URL категории. Для охвата многих категорий ведите карту имён к URL и перебирайте её с короткой задержкой между запросами.
Можно ли парсить «Бестселлеры» для любой категории продуктов?
Большинство категорий можно парсить, поскольку Amazon публикует «Бестселлеры» почти для каждого отдела и многих подкатегорий, каждый со своим списком. Макет страницы единообразен по категориям, поэтому одни и те же селекторы обычно переносятся. Поддерживайте разумный объём и соблюдайте условия и ожидания по частоте запросов Amazon при охвате многих категорий.
В чём разница между парсером BeautifulSoup и встроенным скрапером?
Парсер BeautifulSoup даёт полный контроль над тем, какие поля извлекать и как, ценой поддержки селекторов по мере изменения разметки Amazon. Встроенный скрапер amazon-best-sellers возвращает ранжированный список в виде структурированного JSON напрямую, включая ASIN, изображение и позицию, без необходимости поддерживать селекторы. Используйте встроенный скрапер для скорости и ручной парсер, когда вам нужно поле, которое он не возвращает.
Как отслеживать тенденции «Бестселлеров» со временем?
Запускайте скрапер по расписанию, проставляйте дату каждому экспорту и сохраняйте снимки. Сравнение последовательных запусков показывает, какие продукты поднялись или опустились в рейтинге и как изменились цены. Этот временной ряд превращает одноразовый список в данные о тенденциях, которые можно использовать для исследования продуктов, ценообразования и конкурентного анализа.
Как не получить блокировку при парсинге Amazon?
Поддерживайте низкую частоту запросов с одного IP-адреса, добавляйте задержку между страницами и категориями и маршрутизируйте через ротируемые резидентные IP-адреса, чтобы ни один адрес не превысил лимит. Crawling API управляет ротацией, доверенным пулом IP-адресов и обработкой CAPTCHA за вас; если вы строите собственный стек, это именно та часть, в которую стоит инвестировать. Следите за кодами статусов и замедляйтесь, когда начинаете видеть запросы на проверку.
Обходите любой сайт в масштабе, без борьбы с инфраструктурой.
Crawlbase берёт на себя прокси, отпечатки и CAPTCHA, чтобы ваша команда выпускала конвейеры данных вместо поддержки обвязки краулинга. 1 000 запросов бесплатно, без карты.
