Скрапінг даних товарів 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 Коментаріїв