Скрапинг данных товаров Amazon при помощи Python

Комментарии: 0

Доступ к обширным данным с таких торговых платформ, как 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 requests

2. 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.

1.png

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

2.png

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

3.png

Создадим словарь, который содержит выражения 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 файла:

4.png

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-адресов можно осуществлять скрапинг в больших масштабах. Понимание преимуществ и недостатков каждого типа прокси имеет решающее значение для непрерывного извлечения данных.

Тип Преимущества Недостатки
Прокси дата-центров

Высокая скорость и производительность.

Экономичны.

Идеальны для запросов большого объема.

Легко обнаруживаются и попадают в черные списки.

Ненадежны против систем анти-скрапинга или анти-боттинга.

Резидентские прокси

Высокий траст фактор благодаря реальным IP-адресам.

Высокая вариативность в выборе локаций прокси.

Возможность ротации IP.

Высокая цена.

Мобильные прокси

Высокий траст фактор IP-адресов.

Эффективны для обхода блокировок и проверок со стороны различных систем безопасности.

Высокая цена.

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

ISP прокси

Высокая надежность IP-адресов.

Быстрее, чем резидентские IP-адреса.

Ограниченное количество доступных IP-адресов.

Нет возможности ротации IP.

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

Комментарии:

0 комментариев