Guida allo scraping dei dati di Google Flights con Python

Commenti: 0

Quando si tratta di pianificare viaggi, analizzare la concorrenza o fare ricerche, lo scraping di informazioni sui voli da Google Flights può fornire informazioni significative. Ecco un tutorial passo passo su come effettuare lo scraping di informazioni sui voli utilizzando Python, Playwright e le librerie lxml.

Impostazione dell'ambiente

Prima di immergersi nel processo di scraping, assicurarsi di avere installato le librerie Python necessarie:

pip install playwright
Pip install lxml

Per utilizzare Playwright, è necessario installare anche i binari del browser:

playwright install chromium

Processo di scraping passo dopo passo

Ci concentreremo sull'estrazione dei dati di volo dalla pagina dei risultati di ricerca di Google Flights.

Passo 1. Capire la struttura del sito web

Per estrarre i dati da Google Flights in modo efficace, è necessario familiarizzare con la struttura HTML del sito web. Ecco come utilizzare Chrome DevTools per ispezionare gli elementi e recuperare le espressioni XPath necessarie per lo scraping:

  1. Aprire Chrome DevTools facendo clic con il tasto destro del mouse sulla pagina di Google Flights e selezionando "Inspect", oppure utilizzare la scorciatoia Ctrl+Shift+I (Windows/Linux) o Cmd+Option+I (Mac).
  2. Ispezionare gli elementi passando il mouse su diverse parti della pagina. Questo evidenzierà la struttura HTML nei DevTools. Fare clic sugli elementi specifici per visualizzarne gli attributi, che sono fondamentali per creare espressioni XPath accurate.
  3. Recuperare le espressioni XPath facendo clic con il tasto destro del mouse sull'elemento desiderato nel pannello Elementi, selezionando "Copia" e quindi "Copia XPath". In questo modo si copia l'espressione XPath direttamente negli appunti, pronta per essere utilizzata nello script di scraping.

Elenco delle espressioni XPath utilizzate:

From Location: //input[@aria-label="Where from?"]/@value
To Location: //input[@aria-label="Where to?"]/@value
Departure Date: //input[@placeholder="Departure"]/@value
Return Date: //input[@placeholder="Return"]/@value

Nota: questo XPath restituisce più elementi, ciascuno corrispondente a un singolo volo.

Flight Elements: //li[@class="pIav2d"]
Airway: .//div[@class="sSHqwe tPgKwe ogfYpf"]/span/text()
Details: .//span[@class="mv1WYe"]/@aria-label
Departure Time: .//span[@aria-describedby="gEvJbfc1583"]/span/text()
Arrival Time: .//span[@aria-describedby="gEvJbfc1584"]/span/text()
Travel Time: .//div[@class="gvkrdb AdWm1c tPgKwe ogfYpf"]/text()
Price: .//div[@class="YMlIz FpEdX"]/span/text()

Passo 2. Invio di richieste HTTP ed estrazione del contenuto della pagina con Playwright

Utilizziamo Playwright per interagire con la pagina web ed estrarne il contenuto. Questo approccio aiuta a gestire il contenuto dinamico che JavaScript potrebbe caricare.

L'uso di Playwright aiuta a gestire il contenuto dinamico caricato da JavaScript. Lancia un browser headless, naviga verso l'URL ed estrae il contenuto della pagina.

from playwright.sync_api import sync_playwright

# URL per la pagina di ricerca di Google Flights
url = "https link"

def get_page_content(url):
    """Recupera il contenuto HTML dell'URL dato usando Playwright."""
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)  # Avviare il browser in modalità headless
        context = browser.new_context()  # Creare un nuovo contesto del browser
        page = context.new_page()  # Aprire una nuova pagina
        page.goto(url)  # Navigare all'URL specificato
        content = page.content()  # Ottenere il contenuto della pagina
        browser.close()  # Chiudere il browser
    return content

# Recuperare il contenuto della pagina
page_content = get_page_content(url)

Passo 3. Estrarre i dettagli comuni usando XPath

Successivamente, analizziamo il contenuto HTML della risposta utilizzando lxml per estrarre i dettagli comuni del volo, come le date di partenza e di ritorno.

from lxml import html

# Creazione del parser
tree = html.fromstring(page_content)

# Extracting common flight details using XPath
from_location = tree.xpath('//input[@aria-label="Where from?"]/@value')[0]  # Ottenere la posizione "from
to_location = tree.xpath('//input[@aria-label="Where to?"]/@value')[0]  # Ottenere la posizione 'a'
departure_date = tree.xpath('//input[@placeholder="Departure"]/@value')[0]  # Ottenere la data di partenza
return_date = tree.xpath('//input[@placeholder="Return"]/@value')[0]  # Ottenere la data di ritorno

Passo 4. Estrazione di dati di volo specifici utilizzando lxml

Si analizza quindi il contenuto HTML per estrarre informazioni specifiche sui voli in base alle espressioni XPath identificate.

# Inizializzare un elenco vuoto per memorizzare i dettagli del volo
flights = []

# Estrarre gli elementi di volo dall'HTML analizzato utilizzando XPath
flight_elements = tree.xpath('//li[@class="pIav2d"]')

# Eseguire il loop di ogni elemento di volo ed estrarre i dettagli
for flight in flight_elements:
    # Estrarre il nome della compagnia aerea
    airway = flight.xpath('.//div[@class="sSHqwe tPgKwe ogfYpf"]/span/text()')[0].strip()
    
    # Estrarre i dettagli del volo, ad esempio gli scali
    details = flight.xpath('.//span[@class="mv1WYe"]/@aria-label')[0]
    
    # Estrarre l'orario di partenza
    departure = flight.xpath('.//span[@jscontroller="cNtv4b"]/span/text()')[0].strip()
    
    # Estrarre l'orario di arrivo
    arrival = flight.xpath('.//span[@jscontroller="cNtv4b"]/span/text()')[1].strip()
    
    # Estrarre il tempo di percorrenza totale
    travel_time = flight.xpath('.//div[@class="gvkrdb AdWm1c tPgKwe ogfYpf"]/text()')[0].strip()
    
    # Estrarre il prezzo del volo
    price = flight.xpath('.//div[@class="U3gSDe"]/div/div[2]/span/text()')[0].strip()

    # Aggiungere i dettagli estratti all'elenco dei voli come dizionario
    flights.append({
        'Airway': airway,
        'Details': details,
        'Departure': departure,
        'Arrival': arrival,
        'Travel Time': travel_time,
        'Price': price,
        'From': from_location,
        'To': to_location,
        'Departure Date': departure_date,
        'Return Date': return_date
    })
 

Passo 5. Salvataggio dei dati in CSV

Infine, utilizziamo il modulo CSV di Python per salvare i dati estratti in un file CSV per ulteriori analisi.

import csv

# Definire il percorso del file CSV
csv_file = 'google_flights.csv'

# Definire i nomi dei campi CSV
fieldnames = ['Airway', 'Details', 'Departure', 'Arrival', 'Travel Time', 'Price', 'From', 'To', 'Departure Date', 'Return Date']

# Scrittura dei dati in un file CSV
with open(csv_file, mode='w', newline='', encoding='utf-8') as file:
    writer = csv.DictWriter(file, fieldnames=fieldnames)
    writer.writeheader()
    for flight in flights:
        writer.writerow(flight)

print(f"Data saved to {csv_file}")

Mettere tutto insieme

from playwright.sync_api import sync_playwright
from lxml import html
import csv

# URL per la pagina di ricerca di Google Flights
url = "https link"

def get_page_content(url):
    """Recupera il contenuto HTML dell'URL dato usando Playwright."""
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)  # Avviare il browser in modalità headful
        context = browser.new_context()  # Creare un nuovo contesto del browser
        page = context.new_page()  # Aprire una nuova pagina
        page.goto(url)  # Navigare all'URL specificato
        page.wait_for_timeout(10000)  # Attendere 10 secondi per assicurarsi che la pagina venga caricata completamente.
        content = page.content()  # Ottenere il contenuto della pagina
        browser.close()  # Chiudere il browser
    return content

# Recuperare il contenuto della pagina
page_content = get_page_content(url)

# Analizzare il contenuto HTML utilizzando lxml
tree = html.fromstring(page_content)

# Estrazione dei dettagli di ricerca dei voli
from_location = tree.xpath('//input[@aria-label="Where from?"]/@value')[0]
to_location = tree.xpath('//input[@aria-label="Where to?"]/@value')[0]
departure_date = tree.xpath('//input[@placeholder="Departure"]/@value')[0]
return_date = tree.xpath('//input[@placeholder="Return"]/@value')[0]

# Inizializzare un elenco per memorizzare i dettagli del volo
flights = []

# Estrarre gli elementi di volo dall'HTML analizzato
flight_elements = tree.xpath('//li[@class="pIav2d"]')
for flight in flight_elements:
    airway = flight.xpath('.//div[@class="sSHqwe tPgKwe ogfYpf"]/span/text()')[0].strip()
    details = flight.xpath('.//span[@class="mv1WYe"]/@aria-label')[0]
    departure = flight.xpath('.//span[@jscontroller="cNtv4b"]/span/text()')[0].strip()
    arrival = flight.xpath('.//span[@jscontroller="cNtv4b"]/span/text()')[1].strip()
    travel_time = flight.xpath('.//div[@class="gvkrdb AdWm1c tPgKwe ogfYpf"]/text()')[0].strip()
    price = flight.xpath('.//div[@class="U3gSDe"]/div/div[2]/span/text()')[0].strip()

    #  Aggiungere i dettagli del volo all'elenco
    flights.append({
        'Airway': airway,
        'Details': details,
        'Departure': departure,
        'Arrival': arrival,
        'Travel Time': travel_time,
        'Price': price,
        'From': from_location,
        'To': to_location,
        'Departure Date': departure_date,
        'Return Date': return_date
    })

# Definire il percorso del file CSV
csv_file = 'google_flights.csv'

# Definire i nomi dei campi CSV
fieldnames = ['Airway', 'Details', 'Departure', 'Arrival', 'Travel Time', 'Price', 'From', 'To', 'Departure Date', 'Return Date']

# Scrittura dei dettagli di volo estratti in un file CSV
with open(csv_file, mode='w', newline='', encoding='utf-8') as file:
    writer = csv.DictWriter(file, fieldnames=fieldnames)
    writer.writeheader()  # Scrivere la riga di intestazione
    for flight in flights:
        writer.writerow(flight)  # Scrivere i dettagli di ogni volo

print(f"Data saved to {csv_file}")

Per ridurre il rischio di rilevamento durante lo scraping dei dati, è consigliabile incorporare ritardi tra le richieste e utilizzare i proxy. L'implementazione di ritardi aiuta a simulare l'interazione umana, rendendo più difficile per i siti web rilevare attività di scraping automatizzate. Per la selezione dei proxy, si consigliano i proxy dinamici residenziali, perché offrono un alto livello di fiducia e hanno meno probabilità di essere bloccati a causa della loro natura dinamica. In alternativa, è possibile utilizzare un pool di proxy ISP statici, che forniscono una connessione stabile e veloce, migliorando l'affidabilità del processo di estrazione dei dati. Queste strategie aiutano a eludere le misure di protezione utilizzate dai siti web per identificare e bloccare i bot di scraping.

Commenti:

0 Commenti