Скрапинг данных товаров Amazon при помощи Python
Сводка через AI:
Доступ к обширным данным с таких торговых платформ, как Amazon, крайне важен для анализа рынка, стратегий ценообразования и исследования товаров, и может быть реализован с помощью веб-скрапинга. Тем не менее, Amazon активно защищает свои данные, что значительно усложняет процесс традиционного скрапинга. В этом всестороннем руководстве мы изучим методы сбора данных о товарах Amazon и обсудим, как можно обходить антискрапинговые системы платформы, используя Python, прокси и продвинутые техники скрапинга.
Создание Python скрипта для парсинга информации на Amazon
Успешное выполнение веб-скрапинга возможно при следовании определенному алгоритму, рассмотренному далее.
Шаг 1: Отправка HTTP-запросов на страницы продуктов Amazon:
- Использование библиотеки requests для отправки HTTP GET-запросов на страницы продуктов Amazon.
- Получение исходного HTML-контента из HTTP-ответа.
Шаг 2: Парсинг HTML-контента с помощью LXML и извлечение актуальных данных:
- Использование библиотеки LXML для парсинга полученного исходного HTML-ответа.
- Определение необходимых точек данных в HTML-ответе для извлечения.
- Отправка XPath-запросов для необходимых точек данных и извлечение информации.
Шаг 3: Хранение данных:
- После извлечения необходимых данных необходимо сохранить их в корректных форматах, таких как CSV и JSON.
Преодоление потенциальных сложностей
Amazon применяет определенные действия для предотвращения скрапинга, такие как ограничение скорости соединения, CAPTCHA или блокировка по IP. Пользователь может применять контрмеры для обхода блокировок, используя ра зличные методы, например, использование качественных прокси.
При масштабном скрапинге пользователь может использовать продвинутые техники Python для извлечения больших объемов данных о товарах, включая подмену заголовков и TLS.
Эти шаги будут расписаны подробнее в следующих разделах статьи, где мы увидим их практическую реализацию на Python 3.12.2.
Подготовка предварительных условий
Для начала проекта по веб-скрапингу мы настроим базовый скрапер, используя библиотеку lxml для парсинга HTML и библиотеку requests для обработки HTTP-запросов к веб-серверу Amazon.
Затем мы сосредоточим внимание на извлечении ключевой информации, такой как названия продуктов, цены и рейтинги со страниц товаров Amazon. Также продемонстрируем техники, которые позволяют эффективно парсить HTML и обрабатывать запросы, обеспечивая точное и структурированное извлечение информации.
Для сохранения зависимостей проекта и предотвращения конфликтов рекомендуется создать отдельную виртуальную среду для вашего проекта по веб-скрапингу. Рекомендуется использовать инструменты вроде “venv” или “pyenv” для настройки виртуальных сред.
Установка сторонних библиотек
Понадобятся следующие сторонние библиотеки Python:
1. requests
Используется для отправки HTTP-запросов и получения веб-контента. Часто применяется для веб-скрапинга и взаимодействия с веб-API.
Установка:
pip install requests2. lxml
Библиотека для парсинга и оперирования XML и HTML документами. Часто используется для веб-скрапинга и работы со структурированными данными с веб-страниц.
Установка:
pip install lxmlИмпорт необходимых библиотек
Для начала нужно импортировать необходимые библиотеки для работы скрапера. В частности, библиотеку requests для обработки HTTP-запросов, библиотеку csv для работы с файлами CSV, библиотеку random для генерации случайных значений, библиотеку lxml для парсинга исходного HTML-контента, а также Dict и List для типизации.
import requests
import csv
import random
from lxml import html
from typing import Dict, ListСчитывание входящих данных из файла CSV
Следующий фрагмент кода считывает файл CSV под названием “amazon_product_urls.csv”, где каждая строка содержит URL страницы продукта Amazon. Код считывает строки, извлекая из каждой из них URL и добавляя их в список под названием URL.
with open('amazon_product_urls.csv', 'r') as file:
reader = csv.DictReader(file)
for row in reader:
urls.append(row['url'])Прокси и заголовки HTTP-запросов
Заголовки играют ключевую роль в HTTP-запросах, предоставляя важную информацию о пользователе и запросе. Имитируя стандартные заголовки, скраперы могут эффективно обходить системы обнаружения, обеспечивая надежное извлечение данных.
Прокси-свервера играют роль посредника в веб-скрапинге, маскируя IP-адрес скрапера для предотвращения обнаружения и блокировки сервером. Динамические прокси позволяют отправлять каждый запрос используя новый IP-адрес, тем самым избегая потенциальных блокировок. Использование резидентских или мобильных прокси в этом случае повышает вероятность успешного обхода антискрапинговых технологий благодаря отображению реального хоста и провайдера.
Код для интеграции заголовков запросов и прокси-серверов с авторизацией по IP-адресу:
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'accept-language': 'en-IN,en;q=0.9',
'dnt': '1',
'sec-ch-ua': '"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'same-origin',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
}
proxies = {'http': '', 'https': ''}Ротация User-Agent
Далее мы создадим список различных User-Agent, из которых для каждого запроса будет выбран определенный случайным образом. Реализация механизма ротации заголовков, такого как изменение User-Agent после каждого запроса, может дополнительно помочь в обходе системы обнаружения подозрительной активности со стороны сервера.
useragents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4591.54 Safari/537.36",
"Mozilla/5.0 (Windows NT 7_0_2; Win64; x64) AppleWebKit/541.38 (KHTML, like Gecko) Chrome/105.0.1585 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.7863.44 Safari/537.36"
]
headers['user-agent'] = random.choice(useragnets)Отправка HTTP-запросов на страницу товара через прокси-сервер
Следующая команда отправляет HTTP GET-запрос на указанный URL с пользовательскими заголовками, тайм-аутом в 30 секунд и указанными прокси-сервером для запроса.
response = requests.get(url=url, headers=headers, proxies=proxies, timeout=30)Определение XPath/Селекторов точек данных для начала скрапинга
Необходимые точки данных: н азвание, цена и рейтинг. Проверим и определим соответствие XPath для элементов, показанных на скриншотах, вместе с их данными.
На приведенном ниже скриншоте показана функция "Inspect" в Chrome DevTools, используемая для нахождения XPath “//span[@id="productTitle"]/text()”, для извлечения названия товара с его страницы на Amazon.

На следующем скриншоте показан процесс поиска соответствующего XPath “//div[@id="corePrice_feature_dark"]/div/div/span/span/text()” для извлечения цены товара.

На скриншоте показан процесс поиска соответствующего XPath “//span[@id='acrPopover']/@title” для извлечения рейтинга товара.

Создадим словарь, который содержит выражения XPath для извлечения конкретной информации с веб-страницы: название, рейтинг и цену товара. Вот пример такого словаря:
xpath_queries = {'title': '//span[@id="productTitle"]/text()', 'ratings': '//span[@id="acrPopover"]/@title', 'price': '//span[@class="a-offscreen"]/text()'}Создание парсера lxml из HTML-ответа
Приведенный ниже код анализирует HTML-контент, полученный из GET-запроса к серверу Amazon, преобразуя его в структурированный, древовидный формат. Это упрощает навигацию и оперирование его элементами и значениями:
tree = html.fromstring(response.text)Извлечение данных
Следующий фрагмент кода извлекает данные из проанализированного HTML-дерева с использованием запроса XPath и сохраняет их в словаре с указанным ключом. Метод “strip()” используется для удаления пробелов в начале и конце, если они есть. Код извлекает первый результат запроса XPath и сохраняет его под данным ключом в словаре “extracted_data”:
data = tree.xpath(xpath_query)[0].strip()
extracted_data[key] = dataСохранение данных в CSV файл
Следующий код записывает данные из словаря “extracted_data” в CSV файл с названием “product_data.csv”. Заголовок файла записывается только если файл пуст. Если в файле уже имеется информация, данные добавляются в виде новой строки. Эта функция позволяет непрерывно обновлять CSV файл новыми данными без перезаписи существующего текста:
csv_file_path = 'product_data.csv'
fieldnames = ['title', 'ratings', 'price']
with open(csv_file_path, 'a', newline='') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
if csvfile.tell() == 0:
writer.writeheader()
writer.writerow(extracted_data)Реализация кода
Рекомендуется воспользоваться нашим кодом, который поможет быстро начать работу. Код хорошо структурирован, что делает его удобным для новичков. Для выполнения этого кода у пользователя должен быть CSV файл под названием “amazon_product_urls” в той же директории. Ниже представлена структура CSV файла:

import requests
import csv
import random
from lxml import html
from typing import Dict, List
def send_requests(
url: str, headers: Dict[str, str], proxies: Dict[str, str]
) -> List[Dict[str, str]]:
"""
Отправляет HTTP GET запросы по нескольким URL с использованием заголовков и прокси.
Args:
urls (str): URL для отправки запросов.
headers (Dict[str, str]): Словарь, содержащий заголовки запросов.
proxies (Dict[str, str]): Словарь, содержащий настройки прокси.
Returns:
Response: Объект ответа, содержащий данные ответа для каждого URL.
"""
try:
response = requests.get(url, headers=headers, proxies=proxies, timeout=30)
# Проверка достоверности
if len(response.text)> 10000:
return response
return None
except Exception as e:
print(f"Error occurred while fetching URL {url}: {str(e)}")
def extract_data_from_html(
response, xpath_queries: Dict[str, str]
) -> Dict[str, List[str]]:
"""
Извлекает данные из HTML-контента с использованием запросов XPath.
Args:
response (Response): Объект ответа.
xpath_queries (Dict[str, str]): Словарь, содержащий запросы XPath для извлечения данных.
Returns:
Dict[str, str]: Словарь, содержащий извлеченные данные для каждого запроса XPath.
"""
extracted_data = {}
tree = html.fromstring(response.text)
for key, xpath_query in xpath_queries.items():
data = tree.xpath(xpath_query)[0].strip()
extracted_data[key] = data
return extracted_data
def save_to_csv(extracted_data: Dict[str, any]):
"""
Сохраняет словарь в виде строки в файл CSV с использованием DictWriter.
Args:
extracted_data (Dict[str, any]): Словарь, представляющий строку данных.
"""
csv_file_path = "product_data.csv"
fieldnames = ["title", "ratings", "price"]
with open(csv_file_path, "a", newline="") as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
if csvfile.tell() == 0:
writer.writeheader() # Вписывайте заголовок, только если файл пуст
writer.writerow(extracted_data)
def main():
# Чтение URL-адресов из CSV-файла
urls = []
with open("amazon_product_urls.csv", "r") as file:
reader = csv.DictReader(file)
for row in reader:
urls.append(row["url"])
# Определение заголовков запросов
headers = {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"accept-language": "en-IN,en;q=0.9",
"dnt": "1",
"sec-ch-ua": '"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "same-origin",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
}
useragents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4591.54 Safari/537.36",
"Mozilla/5.0 (Windows NT 7_0_2; Win64; x64) AppleWebKit/541.38 (KHTML, like Gecko) Chrome/105.0.1585 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.7863.44 Safari/537.36"
]
# Указание прокси-сервера
proxies = {"http": "IP:Port", "https": "IP:Port"}
# Отправка запросов к URL-адресам
for url in urls:
# Ротация User-agent в заголовке
headers["user-agent"] = random.choice(useragnets)
response = send_requests(url, headers, proxies)
if response:
# Извлечение данных из содержимого HTML
xpath_queries = {
"title": '//span[@id="productTitle"]/text()',
"ratings": '//span[@id="acrPopover"]/@title',
"price": '//span[@class="a-offscreen"]/text()',
}
extracted_data = extract_data_from_html(response, xpath_queries)
# Сохранение извлеченных данных в файл CSV
save_to_csv(extracted_data)
if __name__ == "__main__":
main()Рекомендации по выбору прокси для скрапинга на Amazon
Существуют различные виды прокси, такие как статические дата-центр прокси IPv4, динамические мобильные прокси, ISP-прокси и резидентские прокси, которые обеспечивают непрерывное извлечение данных. Правильная логика ротации IP-адреса и User-Agent помогают имитировать поведение реальных пользователей. Кроме того, благодаря обширным пулам IP-адресов можно осуществлять скрапинг в больших масштабах. Понимание преимуществ и недостатков каждого типа прокси имеет решающее значение для непрерывного извлечения данных.
Скрапинг данных о товарах на Amazon требует тщательной подготовки к решению проблем, связанных с системами анти-скрапинга на платформе. Использование прокси-серверов в связке с Python позволяет эффективно обрабатывать массив данных и извлекать из него только необходимое. При выборе прокси для веб-скрапинга ключевыми моментами являются баланс производительности, стоимости, надежности этих серверов и специфика проекта. Использование динамических прокси и определенных техник, направленных на противодействие системам безопасности, может помочь снизить риск блокировок, и оптимизировать процесс скрапинга.
