Guida passo-passo al web scraping in Python per i principianti

Commenti: 0

Python è la scelta migliore per lo scraping del web grazie alle sue solide librerie e alla sintassi semplice. In questo articolo esploreremo i fondamenti del web scraping e vi guideremo nella configurazione dell'ambiente Python per creare il vostro primo web scraper. Vi presenteremo le principali librerie Python adatte alle attività di scraping, tra cui Beautiful Soup, Playwright e lxml.

Librerie Python per lo scraping del web

Python mette a disposizione diverse librerie per facilitare il web scraping. Ecco alcune di quelle più comunemente utilizzate:

  • requests: una semplice ed elegante libreria HTTP per Python, utilizzata per inviare richieste HTTP per recuperare pagine web.
  • Beautiful Soup: ottimo per l'analisi di documenti HTML e XML. Crea alberi di parsing dal codice sorgente della pagina che facilitano l'estrazione dei dati.
  • lxml: noto per la sua velocità ed efficienza, lxml è eccellente per l'analisi di documenti XML e HTML.
  • Playwright: uno strumento robusto per lo scraping di contenuti dinamici e l'interazione con le pagine web.

Introduzione alle richieste HTTP

HTTP (HyperText Transfer Protocol) è un protocollo di livello applicativo per il trasferimento di dati sul Web. Si digita un URL nel browser, che genera una richiesta HTTP e la invia al server web. Il server web invia quindi al browser la risposta HTTP che viene visualizzata come pagina HTML. Per lo scraping del web, è necessario imitare questo processo e generare richieste HTTP dal proprio script per ottenere il contenuto HTTP delle pagine web in modo programmatico.

Impostazione dell'ambiente

Innanzitutto, assicuratevi di avere installato Python sul vostro sistema. È possibile scaricarlo dal sito ufficiale di Python.

Un ambiente virtuale aiuta a gestire le dipendenze. Usate questi comandi per creare e attivare un ambiente virtuale:


python -m venv scraping_env
source scraping_env/bin/activate

Quindi, installate i pacchetti necessari usando i seguenti comandi:


pip install requests
pip install beautifulsoup4 
pip install lxml

Costruire uno scraper web con Beautiful Soup

Cominciamo con un semplice scraper web che utilizza la richiesta di scraping di contenuti HTML statici.

Esecuzione della richiesta HTTP GET

Il tipo più comune di richiesta HTTP è la richiesta GET, utilizzata per recuperare dati da un URL specificato. Ecco un esempio di base di come eseguire una richiesta GET a http://example.com.


import requests
url = 'http://example.com'
response = requests.get(url)

Gestione delle risposte HTTP

La libreria requests fornisce diversi modi per gestire ed elaborare la risposta:

Controllare il codice di stato: verificare che la richiesta sia andata a buon fine.


if response.status_code == 200:
    print('Request was successful!')
else:
    print('Request failed with status code:', response.status_code)

Estrazione del contenuto: estrarre il testo o il contenuto JSON dalla risposta.


# Ottenere il contenuto della risposta come testo
page_content = response.text
print(page_content)

# Ottenere il contenuto della risposta come JSON (se la risposta è in formato JSON)
json_content = response.json()
print(json_content)

Gestione degli errori HTTP e di rete

Gli errori HTTP e di rete possono verificarsi quando una risorsa non è raggiungibile, una richiesta è scaduta o il server restituisce uno stato HTTP di errore (ad esempio 404 Not Found, 500 Internal Server Error). Per gestire queste situazioni, si possono usare gli oggetti eccezione sollevati dalle richieste.


import requests

url = 'http://example.com'

try:
    response = requests.get(url, timeout=10)  # Set a timeout for the request
    response.raise_for_status()  # Raises an HTTPError for bad responses
except requests.exceptions.HTTPError as http_err:
    print(f'HTTP error occurred: {http_err}')
except requests.exceptions.ConnectionError:
    print('Failed to connect to the server.')
except requests.exceptions.Timeout:
    print('The request timed out.')
except requests.exceptions.RequestException as req_err:
    print(f'Request error: {req_err}')
else:
    print('Request was successful!')

Estrazione di dati da elementi HTML

Per lo scraping del web, spesso abbiamo bisogno di estrarre dati dal contenuto HTML. In questa parte si parlerà di come individuare ed estrarre i dati dagli elementi HTML con alcune librerie come Beautiful Soup o lxml.

L'HTML (HyperText Markup Language) è il linguaggio di markup standard per la creazione di pagine web. È costituito da elementi annidati rappresentati da tag, come <div>, <p>, <a>, ecc. Ogni tag può avere attributi e contenere testo, altri tag o entrambi.

I selettori XPath e CSS forniscono un modo versatile per selezionare gli elementi HTML in base ai loro attributi o alla loro posizione nel documento.

Trovare selettori XPath e CSS

Durante il web scraping, l'estrazione di dati specifici dalle pagine web richiede spesso l'identificazione dei selettori XPath o CSS corretti per gli elementi HTML. Ecco come trovare questi selettori in modo efficiente:

La maggior parte dei browser web moderni è dotata di strumenti integrati per gli sviluppatori che consentono di ispezionare la struttura HTML delle pagine web. Ecco una guida passo passo su come utilizzare questi strumenti:

  1. Strumenti aperti per gli sviluppatori:
    • In Chrome: Fare clic con il tasto destro del mouse sulla pagina e selezionare "Ispeziona" oppure premere Ctrl+Shift+I (Windows/Linux) o Cmd+Opt+I (Mac).
    • In Firefox: Fare clic con il tasto destro del mouse sulla pagina e selezionare "Ispeziona elemento" oppure premere Ctrl+Maiusc+I (Windows/Linux) o Cmd+Opt+I (Mac).
  2. Ispezionare l'elemento:
    • Usare lo strumento di ispezione (l'icona di un cursore) per passare il mouse sull'elemento che si desidera raschiare. In questo modo si evidenzierà l'elemento nella vista della struttura HTML.
  3. Copia il selettore XPath o CSS:
    • Fare clic con il tasto destro del mouse sull'elemento HTML evidenziato nel riquadro degli strumenti di sviluppo.
    • Selezionare "Copia" e poi scegliere "Copia XPath" o "Copia selettore" (selettore CSS).

1n.png

XPath: /html/body/div/h1

CSS Selector: body > div > h1

Estrazione con Beautiful Soup

Beautiful Soup è una libreria Python per l'analisi di documenti HTML e XML. Fornisce metodi e attributi semplici per navigare e cercare nella struttura HTML.


from bs4 import BeautifulSoup
import requests

# URL della pagina web da scrapare
url = 'https://example.com'

# Inviare una richiesta HTTP GET all'URL
response = requests.get(url)

# Analizzare il contenuto HTML della risposta usando Beautiful Soup
soup = BeautifulSoup(response.content, 'html.parser')

# Utilizzare il selettore CSS per trovare tutti i tag <h1> che si trovano all'interno di tag <div>
# che sono figli diretti del tag <body>.
h1_tags = soup.select('body > div > h1')

# Iterare l'elenco dei tag <h1> trovati e stampare il loro contenuto testuale
for tag in h1_tags:
    print(tag.text)

Gestione degli errori di parsing

Gli errori di parsing si verificano quando la struttura HTML o XML non è quella prevista, causando problemi nell'estrazione dei dati. Questi possono essere gestiti gestendo eccezioni come AttributeError.


from bs4 import BeautifulSoup
import requests

# URL della pagina web da scrapare
url = 'https://example.com'

# Inviare una richiesta HTTP GET all'URL
response = requests.get(url)

try:
    # Analizzare il contenuto HTML della risposta usando Beautiful Soup
    soup = BeautifulSoup(response.content, 'html.parser')

    # Utilizzare il selettore CSS per trovare tutti i tag <h1> che si trovano all'interno di tag <div>
    # che sono figli diretti del tag <body>.
    h1_tags = soup.select('body > div > h1')

    # Iterare l'elenco dei tag <h1> trovati e stampare il loro contenuto testuale
    for tag in h1_tags:
        print(tag.text)
except AttributeError as attr_err:
    # Gestire i casi in cui potrebbe verificarsi un AttributeError (ad esempio, se il response.content è None)
    print(f'Attribute error occurred: {attr_err}')
except Exception as parse_err:
    # Gestire altre eccezioni che potrebbero verificarsi durante il parsing
    print(f'Error while parsing HTML: {parse_err}')

Estrazione con lxml

Oltre a Beautiful Soup, un'altra libreria popolare per il parsing di documenti HTML e XML in Python è lxml. Mentre BeautifulSoup si concentra sulla fornitura di una comoda interfaccia per la navigazione e la manipolazione dei dati analizzati, lxml è nota per la sua velocità e flessibilità, che la rendono una scelta preferibile per le attività critiche dal punto di vista delle prestazioni.


from lxml.html import fromstring
import requests

# URL della pagina web da scrapare
url = 'https://example.com'

# Inviare una richiesta HTTP GET all'URL
response = requests.get(url)

# Analizzare il contenuto HTML della risposta utilizzando il metodo fromstring di lxml
parser = fromstring(response.text)

# Usare XPath per trovare il contenuto del testo del primo tag <h1>
# che si trova all'interno di un tag <div>, figlio diretto del tag <body>.
title = parser.xpath('/html/body/div/h1/text()')[0]

# Stampa del titolo
print(title)

Gestione degli errori di parsing

Simile a Beautiful Soup, lxml consente di gestire gli errori di parsing con grazia, catturando eccezioni come lxml.etree.XMLSyntaxError.


from lxml.html import fromstring
from lxml import etree
import requests

# URL della pagina web da scrapare
url = 'https://example.com'

# Inviare una richiesta HTTP GET all'URL
response = requests.get(url)

try:
    # Analizzare il contenuto HTML della risposta utilizzando il metodo fromstring di lxml
    parser = fromstring(response.text)

    # Usare XPath per trovare il contenuto del testo del primo tag <h1>
    # che si trova all'interno di un tag <div>, figlio diretto del tag <body>.
    title = parser.xpath('/html/body/div/h1/text()')[0]

    # Stampa del titolo
    print(title)
except IndexError:
    # Gestire il caso in cui la query XPath non restituisca alcun risultato
    print('No <h1> tag found in the specified location.')
except etree.XMLSyntaxError as parse_err:
    # Gestire gli errori di sintassi XML durante l'analisi
    print(f'Error while parsing HTML: {parse_err}')
except Exception as e:
    # Gestire qualsiasi altra eccezione
    print(f'An unexpected error occurred: {e}')

Salvataggio dei dati estratti

Una volta estratti con successo i dati dagli elementi HTML, il passo successivo è salvare questi dati. Python offre diverse opzioni per salvare i dati estratti, tra cui il salvataggio in file CSV, JSON e database. Ecco una panoramica su come salvare i dati estratti utilizzando diversi formati:

Salvataggio dei dati in un file CSV

CSV (Comma-Separated Values) è un formato semplice e ampiamente utilizzato per memorizzare dati tabellari. Il modulo CSV di Python facilita la scrittura di dati in file CSV.


import csv

# Dati di esempio
data = {
    'title': 'Example Title',
    'paragraphs': ['Paragraph 1', 'Paragraph 2', 'Paragraph 3']
}

# Salvare i dati in un file CSV
with open('scraped_data.csv', mode='w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerow(['Title', 'Paragraph'])
    for paragraph in data['paragraphs']:
        writer.writerow([data['title'], paragraph])

print('Data saved to scraped_data.csv')

Salvataggio dei dati in un file JSON

JSON (JavaScript Object Notation) è un formato leggero per lo scambio di dati, facile da leggere e scrivere. Il modulo JSON di Python fornisce metodi per salvare i dati in formato JSON.


import json

# Dati di esempio
data = {
    'title': 'Example Title',
    'paragraphs': ['Paragraph 1', 'Paragraph 2', 'Paragraph 3']
}

# Salvare i dati in un file JSON
with open('scraped_data.json', mode='w', encoding='utf-8') as file:
    json.dump(data, file, ensure_ascii=False, indent=4)

print('Data saved to scraped_data.json')

Tecniche avanzate di web scraping con Playwright

Playwright è un potente strumento per lo scraping di contenuti dinamici e l'interazione con gli elementi web. È in grado di gestire siti web pesanti in JavaScript che i parser HTML statici non sono in grado di gestire.

Installare Playwright e configurarlo:


pip install playwright
playwright install

Scraping di contenuti dinamici

Playwright consente di interagire con elementi web come la compilazione di moduli e il clic su pulsanti. Può attendere il completamento delle richieste AJAX prima di procedere, il che lo rende ideale per lo scraping di contenuti dinamici.

2n.png

Il codice fornito esegue lo scraping di una pagina di prodotto Amazon utilizzando Playwright e lxml. Inizialmente, vengono importati i moduli necessari. Viene definita una funzione di esecuzione per incapsulare la logica di scraping. La funzione inizia impostando un server proxy e lanciando una nuova istanza del browser con il proxy e in modalità non headless, consentendo di osservare le azioni del browser. Nel contesto del browser, viene aperta una nuova pagina e si naviga verso l'URL del prodotto Amazon specificato, con un timeout di 60 secondi per garantire il caricamento completo della pagina.

Lo script interagisce quindi con la pagina per selezionare uno specifico stile di prodotto da un menu a discesa e un'opzione di prodotto utilizzando i localizzatori e la corrispondenza del testo. Dopo essersi assicurato che queste interazioni siano state completate e che la pagina sia stata caricata completamente, viene acquisito il contenuto HTML della pagina.

Il contenuto HTML viene quindi analizzato utilizzando il metodo fromstring di lxml per creare un albero di elementi. Una query XPath viene utilizzata per estrarre il contenuto testuale del titolo del prodotto da un elemento specifico con l'ID productTitle. Lo script include la gestione degli errori per gestire i casi in cui la query XPath non restituisce risultati, in cui si verificano errori di sintassi XML durante l'analisi o altre eccezioni impreviste. Infine, il titolo del prodotto estratto da tlxml viene stampato e il contesto e il browser vengono chiusi per terminare la sessione.

La funzione di esecuzione viene eseguita all'interno di una sessione Playwright avviata da sync_playwright, assicurando che l'intero processo sia gestito ed eseguito in un ambiente controllato. Questa struttura garantisce robustezza e resistenza agli errori durante l'esecuzione dell'attività di scraping del web.


from playwright.sync_api import Playwright, sync_playwright
from lxml.html import fromstring, etree


def run(playwright: Playwright) -> None:
   # Definire il server proxy
   proxy = {"server": "https://IP:PORT", "username": "LOGIN", "password": "PASSWORD"}

   # Avvia una nuova istanza del browser con il proxy specificato e in modalità non headless.
   browser = playwright.chromium.launch(
       headless=False,
       proxy=proxy,
       slow_mo=50,
       args=['--ignore-certificate-errors'],
   )

   # Creare un nuovo contesto del browser
   context = browser.new_context(ignore_https_errors=True)

   # Aprire una nuova pagina nel contesto del browser
   page = context.new_page()

   # Navigare alla pagina del prodotto Amazon specificato
   page.goto(
       "https://www.amazon.com/A315-24P-R7VH-Display-Quad-Core-Processor-Graphics/dp/B0BS4BP8FB/",
       timeout=10000,
   )

   # Attendere il caricamento completo della pagina
   page.wait_for_load_state("load")

   # Selezionate uno stile di prodotto specifico dal menu a tendina
   page.locator("#dropdown_selected_style_name").click()

   # Selezionare un'opzione di prodotto specifica
   page.click('//*[@id="native_dropdown_selected_style_name_1"]')
   page.wait_for_load_state("load")

   # Ottenere il contenuto HTML della pagina caricata
   html_content = page.content()

   try:
       # Analizzare il contenuto HTML utilizzando il metodo fromstring di lxml
       parser = fromstring(html_content)

       # Utilizzare XPath per estrarre il contenuto testuale del titolo del prodotto
       product_title = parser.xpath('//span[@id="productTitle"]/text()')[0].strip()

       # Stampa il titolo del prodotto estratto
       print({"Product Title": product_title})
   except IndexError:
       # Gestire il caso in cui la query XPath non restituisce alcun risultato
       print('Product title not found in the specified location.')
   except etree.XMLSyntaxError as parse_err:
       # Gestire gli errori di sintassi XML durante l'analisi
       print(f'Error while parsing HTML: {parse_err}')
   except Exception as e:
       # Gestire qualsiasi altra eccezione
       print(f'An unexpected error occurred: {e}')

   # Chiudere il contesto del browser e il browser
   context.close()
   browser.close()


# Usare sync_playwright per avviare la sessione di Playwright ed eseguire lo script
with sync_playwright() as playwright:
   run(playwright)

Il web scraping con Python è un metodo potente per raccogliere dati dai siti web. Gli strumenti discussi facilitano l'estrazione, l'elaborazione e l'archiviazione dei dati web per vari scopi. In questo processo, l'uso di server proxy per alternare gli indirizzi IP e l'implementazione di ritardi tra le richieste sono fondamentali per aggirare i blocchi. Beautiful Soup è facile da usare per i principianti, mentre lxml è adatto per gestire grandi insiemi di dati grazie alla sua efficienza. Per le esigenze di scraping più avanzate, soprattutto con siti web caricati dinamicamente in JavaScript, Playwright si dimostra molto efficace.

Commenti:

0 Commenti