Scraping di dati sui prodotti Amazon con Python

Commenti: 0

L'accesso ai dati di giganti dell'e-commerce come Amazon è fondamentale per le analisi di mercato, le strategie di prezzo e la ricerca sui prodotti. Questi dati possono essere raccolti attraverso il web scraping, un metodo che prevede l'estrazione di grandi quantità di informazioni dai siti web. Tuttavia, Amazon protegge rigorosamente i suoi dati, rendendo spesso inefficaci le tecniche di scraping tradizionali. In questa guida completa, approfondiremo i metodi di raccolta dei dati sui prodotti da Amazon e discuteremo le strategie per aggirare i solidi sistemi anti-scraping della piattaforma. Esploreremo l'uso di Python, di proxy e di tecniche di scraping avanzate che possono aiutare a superare queste sfide e a raccogliere in modo efficiente i dati necessari per i vostri scopi commerciali o di ricerca.

Creazione di uno script Python per lo scraping dei dati Amazon

Per eseguire con successo lo scraping di dati da Amazon, è possibile seguire l'algoritmo strutturato descritto di seguito. Questo metodo garantisce il recupero delle informazioni necessarie in modo efficiente e accurato.

Fase 1: invio di richieste HTTP alle pagine dei prodotti Amazon:

  • Utilizzare la libreria delle richieste per avviare richieste HTTP GET dirette alle pagine dei prodotti di Amazon;
  • Catturare il contenuto HTML grezzo dalla risposta HTTP per prepararlo all'analisi.

Fase 2: Parsing del contenuto HTML:

  • Impiegare la libreria lxml per analizzare il contenuto HTML grezzo ricevuto.
  • Analizzare l'HTML per localizzare i punti di dati specifici che si desidera estrarre;
  • Eseguire le query XPath per individuare ed estrarre con precisione questi punti di dati dalla struttura HTML.

Fase 3: memorizzare i dati:

  • Dopo aver estratto i dati necessari, procedere al loro salvataggio in formati accessibili come CSV o JSON, che facilitano l'analisi e l'integrazione con altre applicazioni.

Gestire i potenziali ostacoli

Amazon adotta diverse misure per ostacolare gli sforzi di scraping, tra cui limitazioni della velocità di connessione, integrazione di CAPTCHA e blocco dell'IP. Gli utenti possono adottare contromisure per aggirare questi ostacoli, come l'utilizzo di proxy di alta qualità.

Per le attività di scraping più estese, è possibile utilizzare tecniche Python avanzate per raccogliere quantità sostanziali di dati sui prodotti. Queste tecniche includono l'header stuffing e il TLS fingerprinting, che aiutano a eludere il rilevamento e a garantire il successo dell'estrazione dei dati.

Questi passaggi sono spiegati nelle prossime sezioni dell'articolo, dove ne vedremo l'implementazione pratica utilizzando Python 3.12.2.

Prequisiti

Per avviare un progetto di web scraping, inizieremo con l'impostare uno scraper di base utilizzando la libreria lxml per l'analisi dell'HTML e la libreria requests per gestire le richieste HTTP dirette al server web di Amazon.

Ci concentreremo sull'estrazione di informazioni essenziali come i nomi dei prodotti, i prezzi e le valutazioni dalle pagine dei prodotti Amazon. Verranno inoltre illustrate le tecniche per analizzare in modo efficiente l'HTML e gestire le richieste, garantendo un'estrazione precisa e organizzata dei dati.

Per mantenere le dipendenze del progetto ed evitare conflitti, è consigliabile creare un ambiente virtuale separato per questa attività di web scraping. Si consiglia di utilizzare strumenti come "venv" o "pyenv" per la creazione di ambienti virtuali.

Installare librerie di terze parti

Sono necessarie le seguenti librerie Python di terze parti:

1. richieste

Utilizzata per inviare richieste HTTP e recuperare contenuti web. È spesso usata per il web scraping e per interagire con le API web.

Installazione:

 pip install requests

2. lxml

Libreria per il parsing e la manipolazione di documenti XML e HTML. È spesso usata per il web scraping e per lavorare con i dati strutturati delle pagine web.

Installazione:

 pip install lxml

Importare le librerie necessarie

Qui dobbiamo importare le librerie necessarie per l'esecuzione del nostro scraper. Queste includono una libreria request per gestire le richieste HTTP, una libreria CSV per gestire le operazioni su file CSV, una libreria random per generare valori casuali e fare scelte casuali, una libreria lxml per analizzare il contenuto HTML grezzo e Dict e List per il suggerimento dei tipi.

 import requests
import csv
import random
from lxml import html
from typing import Dict, List

Lettura degli input dal file CSV

Il seguente frammento di codice legge un file CSV chiamato amazon_product_urls.csv, dove ogni riga contiene l'URL di una pagina di prodotto Amazon. Il codice itera sulle righe, estraendo gli URL da ogni riga e aggiungendoli a un elenco chiamato URL.

 with open('amazon_product_urls.csv', 'r') as file:
    reader = csv.DictReader(file)
    for row in reader:
        urls.append(row['url'])

Intestazioni di richiesta HTTP e proxy

Le intestazioni delle richieste svolgono un ruolo importante nelle richieste HTTP, fornendo informazioni complesse sul client e sulla richiesta. Durante lo scraping, è importante copiare i titoli degli utenti autorizzati per evitare il rilevamento e accedere facilmente alle informazioni desiderate. Imitando le intestazioni comunemente utilizzate, gli scrapers possono evitare le tecniche di rilevamento, assicurando l'estrazione dei dati in modo coerente e mantenendo gli standard etici.

I proxy fungono da intermediari nello scraping del Web, mascherando l'indirizzo IP dello scraper per evitare il rilevamento e il blocco del server. Un proxy a rotazione consente di inviare ogni richiesta con un nuovo indirizzo IP evitando potenziali blocchi. L'uso di proxy residenziali o mobili rafforza la resistenza alle misure antiscraping grazie al rilevamento dell'host e del provider reali.

Codice per integrare le intestazioni delle richieste e i server proxy con l'autorizzazione degli indirizzi 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': ''}

Rotazione dell'utente

In questo caso, si creerà un elenco di raccolte di user agent, da cui verrà scelto un user agent casuale per ogni richiesta. L'implementazione di un meccanismo di rotazione delle intestazioni, come la rotazione dello User-Agent dopo ogni richiesta, può aiutare ulteriormente a eludere le misure di rilevamento dei bot.

 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)

Effettuare richieste HTTP alla pagina dei prodotti di Amazon con intestazioni e proxy

Invia una richiesta HTTP GET a un URL specificato con intestazioni personalizzate, un timeout di 30 secondi e i proxy specificati per la richiesta.

response = requests.get(url=url, headers=headers, proxies=proxies, timeout=30)

Identificazione di XPath/Selettori dei punti dati richiesti<

Punti di dati richiesti: titolo, prezzo e valutazioni. Ora, ispezioniamo e identifichiamo l'XPath corrispondente per gli elementi mostrati nelle schermate e i rispettivi punti di dati.

L'immagine seguente mostra l'uso della funzione "Inspect" di Chrome DevTools per trovare l'XPath `//span[@id="productTitle"]/text()` per estrarre il titolo del prodotto da una pagina di prodotto Amazon.

1.png

La schermata seguente mostra la ricerca del percorso XPath `/div[@id="corePrice_feature_div"]/div/div/span/span/text()` per estrarre il prezzo del prodotto da una pagina di prodotto Amazon.

2.png

La schermata mostra il reperimento del percorso XPath `//span[@id="acrPopover"]/@title'` per estrarre le valutazioni dei prodotti da una pagina di prodotti Amazon.

3.png

Creare un dizionario che fornisca espressioni XPath per estrarre informazioni specifiche da una pagina web: il titolo, le valutazioni e il prezzo di un prodotto.

xpath_queries = {'title': '//span[@id="productTitle"]/text()', 'ratings': '//span[@id="acrPopover"]/@title', 'price': '//span[@class="a-offscreen"]/text()'}

Creazione del parser lxml dalla risposta HTML

Il codice sottostante analizza il contenuto HTML ottenuto dalla richiesta GET al server Amazon in un formato strutturato ad albero, che consente una più facile navigazione e manipolazione degli elementi e degli attributi.

tree = html.fromstring(response.text)

Estrarre i dati necessari

Il seguente frammento di codice estrae i dati dall'albero HTML analizzato utilizzando una query XPath e li assegna a un dizionario con una chiave specificata. strip() viene utilizzato per rimuovere gli spazi bianchi all'inizio e alla fine, se presenti. Recupera il primo risultato della query XPath e lo memorizza sotto la chiave indicata nel dizionario extracted_data.

data = tree.xpath(xpath_query)[0].strip()
extracted_data[key] = data

Salvataggio dei dati estratti in CSV

Il codice seguente scrive i dati del dizionario extracted_data in un file CSV chiamato product_data.csv. Assicurarsi che la riga di intestazione venga scritta solo se il file è vuoto. Se il file non è vuoto, aggiunge i dati come riga aggiuntiva al file CSV. Questa funzione consente di aggiornare continuamente il file CSV con i nuovi dati estratti senza sovrascrivere il testo esistente.

 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)

Implementazione del codice

Si prega di consultare il nostro codice completo, che vi aiuterà a iniziare rapidamente. Il codice è ben strutturato e documentato, il che lo rende adatto ai principianti. Per eseguire questo codice, l'utente deve avere un file CSV chiamato "amazon_product_urls" nella stessa directory. Di seguito è riportata la struttura del file 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]]:
    """
    Invia richieste HTTP GET a più URL con intestazioni e proxy.

    Args:
        urls (str): URL a cui inviare le richieste.
        headers (Dict[str, str]): Dizionario contenente le intestazioni della richiesta.
        proxies (Dict[str, str]): Dizionario contenente le impostazioni del proxy.

    Returns:
        Response: Oggetto Response contenente i dati di risposta per ogni URL.
    """
    try:
        response = requests.get(url, headers=headers, proxies=proxies, timeout=30)
        # Response validation
        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]]:
    """
    Estrae dati dal contenuto HTML utilizzando query XPath.

    Args:
        response (Response): Oggetto della risposta.
        xpath_queries (Dict[str, str]): Dizionario contenente le query XPath per l'estrazione dei dati.

    Returns:
        Dict[str, str]: Dizionario contenente i dati estratti per ogni query 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]):
    """
    Salva un dizionario come riga in un file CSV usando DictWriter.

    Args:
        extracted_data (Dict[str, any]): Dizionario che rappresenta una riga di dati.
    """
    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()  # Scrivere l'intestazione solo se il file è vuoto
        writer.writerow(extracted_data)


def main():
    # Lettura degli URL da un file CSV
    urls = []
    with open("amazon_product_urls.csv", "r") as file:
        reader = csv.DictReader(file)
        for row in reader:
            urls.append(row["url"])

    # Definizione delle intestazioni della richiesta
    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"
        ]

    # Definizione dei proxy
    proxies = {"http": "IP:Port", "https": "IP:Port"}

    # Invio di richieste agli URL
    for url in urls:
        # Rotazione degli useragent nelle intestazioni
        headers["user-agent"] = random.choice(useragnets)
        response = send_requests(url, headers, proxies)
        if response:
            # Estrazione di dati dal contenuto 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)

            # Salvataggio dei dati estratti in un file CSV
            save_to_csv(extracted_data)


if __name__ == "__main__":
    main()

Suggerimenti di proxy per lo scraping di Amazon attraverso Python

Sono disponibili diverse soluzioni proxy, tra cui Datacenter IPv4, proxy mobili a rotazione, ISP e residenziali, per un'estrazione dei dati senza interruzioni. Per simulare il comportamento reale degli utenti vengono utilizzati una logica di rotazione e agenti utente adeguati, mentre i proxy speciali supportano lo scraping su larga scala con rotazione interna e pool di IP estesi. La comprensione dei pro e dei contro di ciascuna opzione di proxy è fondamentale per l'estrazione ininterrotta dei dati.

Tipo Pro Contro
Proxy per data center

Alta velocità e prestazioni.

Convenienza economica.

Ideale per richieste di grandi volumi.

Può essere facilmente individuato e inserito nella lista nera.

Non è affidabile contro i sistemi anti-scraping o anti-bot.

Deleghe residenziali

Elevata legittimità grazie a IP residenziali reali.

Ampia disponibilità di IP globali per lo scraping di dati specifici della località.

Capacità di rotazione degli IP.

Più costoso dei proxy dei datacenter.

Proxy mobili

IP altamente legittimi.

Efficace per evitare blocchi e richieste di verifica.

Più costoso di altri tipi di proxy.

Più lento dei proxy dei centri dati a causa della dipendenza dalla rete mobile.

Proxy ISP

IP altamente affidabili.

Più veloci degli IP residenziali.

Disponibilità limitata di IP.

Rotazione IP non disponibile.

Lo scraping dei dati dei prodotti da Amazon richiede una preparazione meticolosa per superare efficacemente i meccanismi anti-scraping della piattaforma. L'utilizzo di server proxy insieme a Python consente un'elaborazione efficiente dei dati e l'estrazione mirata delle informazioni necessarie. Quando si scelgono i proxy per lo scraping del web, è fondamentale considerare fattori come le prestazioni, il costo, l'affidabilità del server e i requisiti specifici del progetto. L'impiego di proxy dinamici e l'implementazione di strategie per contrastare le misure di sicurezza possono ridurre al minimo il rischio di essere bloccati e migliorare l'efficienza complessiva del processo di scraping.

Commenti:

0 Commenti