Come raschiare i dati di Booking.com usando Python

Commenti: 0

In questo articolo dimostreremo come raccogliere dati dal sito web di Booking.com con Python. Otterremo informazioni che includono, ma non solo, nomi di hotel, valutazioni, prezzi, indirizzi di località e relative descrizioni. Il codice fornito consente di recuperare i dati dalle pagine degli hotel analizzando il contenuto HTML ed estraendo i dati JSON incorporati.

Installazione delle librerie necessarie

Prima di eseguire il codice per lo scraping dei dati da Booking.com, è necessario installare le librerie Python necessarie. Ecco come installare le dipendenze necessarie:

  1. Requests Libreria: Viene utilizzata per inviare richieste HTTP al sito web e recuperare il contenuto HTML delle pagine.
  2. LXML Libreria: Viene utilizzata per analizzare il contenuto HTML ed estrarre i dati utilizzando XPath.
  3. JSON: Modulo Python integrato utilizzato per gestire i dati JSON.
  4. CSV: Modulo Python integrato utilizzato per scrivere i dati scrapati in un file CSV.

Per installare le librerie necessarie, si può usare pip:


pip install requests lxml

Queste sono le uniche librerie esterne necessarie e le altre (json, csv) sono preinstallate con Python.

Comprendere l'URL e la struttura dei dati

Quando si effettua lo scraping di dati da Booking.com, è importante capire la struttura della pagina web e il tipo di dati che si desidera estrarre. Ogni pagina di hotel su Booking.com contiene dati strutturati incorporati sotto forma di JSON-LD, un formato che consente di estrarre facilmente dettagli come nome, posizione e prezzi. Noi faremo lo scraping di questi dati.

Processo di scraping passo per passo

Poiché Booking.com è un sito dinamico e implementa misure per contrastare le azioni automatiche, utilizzeremo intestazioni HTTP e proxy appropriati per garantire uno scraping senza interruzioni e senza rischi di blocco.

Invio di richieste HTTP con intestazioni

Le intestazioni simulano una sessione utente in un browser e impediscono il rilevamento da parte dei sistemi antiscraping di Booking.com. Senza intestazioni correttamente configurate, il server può facilmente identificare script automatizzati, il che può portare al blocco dell'IP o a problemi di captcha.

Per evitare di essere bloccati dai meccanismi antiscraping di Booking.com, utilizzeremo intestazioni personalizzate per simulare la navigazione di un utente legittimo sul sito web. Ecco come inviare una richiesta HTTP con intestazioni corrette:


import requests
from lxml.html import fromstring

urls_list = ["https links"]

for url in urls_list:
    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',
        'cache-control': 'no-cache',
        'dnt': '1',
        'pragma': 'no-cache',
        'priority': 'u=0, i',
        'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Linux"',
        'sec-fetch-dest': 'document',
        'sec-fetch-mode': 'navigate',
        'sec-fetch-site': 'none',
        'sec-fetch-user': '?1',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
    }

    response = requests.get(url, headers=headers)

Importanza delle deleghe

L'uso dei proxy è necessario quando si effettua lo scraping di siti come Booking.com, che applicano limiti severi alla velocità delle richieste o tracciano gli indirizzi IP. I proxy aiutano a distribuire il carico delle richieste su diversi indirizzi IP, evitando i blocchi. A tale scopo, è possibile utilizzare sia proxy gratuiti che servizi proxy a pagamento con autenticazione tramite nome utente e password o indirizzo IP. Nel nostro esempio, utilizziamo quest'ultima opzione.


proxies = {
    'http': '',
    'https': ''
}
response = requests.get(url, headers=headers, proxies=proxies)

Parlare l'HTML ed estrarre i dati JSON

Dopo aver inviato la richiesta, analizziamo il contenuto HTML utilizzando lxml per individuare i dati JSON-LD incorporati che contengono i dettagli dell'hotel. Questa fase estrae i dati strutturati dalla pagina web, che comprendono nomi di hotel, prezzi, località e altro ancora.


parser = fromstring(response.text)

# Estrarre i dati JSON incorporati
embeded_jsons = parser.xpath('//script[@type="application/ld+json"]/text()')
json_data = json.loads(embeded_jsons[0])

Estrazione delle informazioni sull'hotel

Una volta analizzati i dati JSON, possiamo estrarre i campi rilevanti come il nome dell'hotel, l'indirizzo, la valutazione e il prezzo. Di seguito è riportato il codice per estrarre le informazioni sull'hotel dal JSON:


name = json_data['name']
location = json_data['hasMap']
priceRange = json_data['priceRange']
description = json_data['description']
url = json_data['url']
ratingValue = json_data['aggregateRating']['ratingValue']
reviewCount = json_data['aggregateRating']['reviewCount']
type_ = json_data['@type']
postalCode = json_data['address']['postalCode']
addressLocality = json_data['address']['addressLocality']
addressCountry = json_data['address']['addressCountry']
addressRegion = json_data['address']['addressRegion']
streetAddress = json_data['address']['streetAddress']
image_url = json_data['image']
room_types = parser.xpath("//a[contains(@href, '#RD')]/span/text()")

# Aggiungere i dati all'elenco all_data
all_data.append({
    "Name": name,
    "Location": location,
    "Price Range": priceRange,
    "Rating": ratingValue,
    "Review Count": reviewCount,
    "Type": type_,
    "Postal Code": postalCode,
    "Address Locality": addressLocality,
    "Country": addressCountry,
    "Region": addressRegion,
    "Street Address": streetAddress,
    "URL": url,
    "Image URL": image_url,
    "Room Types": room_types
})

Salvare i dati in CSV

Una volta estratti i dati, possiamo salvarli in un file CSV per ulteriori analisi:


# Dopo l'elaborazione di tutti gli URL, scrivere i dati in un file CSV.
with open('booking_data.csv', 'w', newline='') as csvfile:
    fieldnames = ["Name", "Location", "Price Range", "Rating", "Review Count", "Type", "Postal Code", 
                  "Address Locality", "Country", "Region", "Street Address", "URL", "Image URL", "Room Types"]
    
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    
    # Scrivere l'intestazione
    writer.writeheader()
    
    # Scrivere le righe di dati
    writer.writerows(all_data)

Codice completo

Ecco il codice completo che combina tutte le sezioni:


import requests
from lxml.html import fromstring
import json
import csv

# Elenco degli URL degli hotel da analizzare
urls_list = [
    "Https link", 
    "Https link"
]

# Inizializzare un elenco vuoto per contenere tutti i dati scrapati
all_data = []

proxies = {
    'http': ''
}

# Eseguire il loop di ogni URL per raschiare i dati
for url in urls_list:
    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',
        'cache-control': 'no-cache',
        'dnt': '1',
        'pragma': 'no-cache',
        'priority': 'u=0, i',
        'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Linux"',
        'sec-fetch-dest': 'document',
        'sec-fetch-mode': 'navigate',
        'sec-fetch-site': 'none',
        'sec-fetch-user': '?1',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
    }

    # Invio della richiesta al sito web
    response = requests.get(url, headers=headers, proxies=proxies)
    
    # Parsing del contenuto HTML
    parser = fromstring(response.text)
    
    # Estrarre i dati JSON incorporati
    embeded_jsons = parser.xpath('//script[@type="application/ld+json"]/text()')
    json_data = json.loads(embeded_jsons[0])

    # Estrarre tutti i dettagli dell'hotel da JSON
    name = json_data['name']
    location = json_data['hasMap']
    priceRange = json_data['priceRange']
    description = json_data['description']
    url = json_data['url']
    ratingValue = json_data['aggregateRating']['ratingValue']
    reviewCount = json_data['aggregateRating']['reviewCount']
    type_ = json_data['@type']
    postalCode = json_data['address']['postalCode']
    addressLocality = json_data['address']['addressLocality']
    addressCountry = json_data['address']['addressCountry']
    addressRegion = json_data['address']['addressRegion']
    streetAddress = json_data['address']['streetAddress']
    image_url = json_data['image']

    room_types = parser.xpath("//a[contains(@href, '#RD')]/span/text()")
    
    # Aggiungere i dati all'elenco all_data
    all_data.append({
        "Name": name,
        "Location": location,
        "Price Range": priceRange,
        "Rating": ratingValue,
        "Review Count": reviewCount,
        "Type": type_,
        "Postal Code": postalCode,
        "Address Locality": addressLocality,
        "Country": addressCountry,
        "Region": addressRegion,
        "Street Address": streetAddress,
        "URL": url,
        "Image URL": image_url,
        "Room Types": room_types
    })

# Dopo l'elaborazione di tutti gli URL, scrivere i dati in un file CSV.
with open('booking_data.csv', 'w', newline='') as csvfile:
    fieldnames = ["Name", "Location", "Price Range", "Rating", "Review Count", "Type", "Postal Code", 
                  "Address Locality", "Country", "Region", "Street Address", "URL", "Image URL", "Room Types"]
    
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    
    # Scrivere l'intestazione
    writer.writeheader()
    
    # Scrivere le righe di dati
    writer.writerows(all_data)

print("Data successfully saved to booking_data.csv")

Questo articolo ha mostrato come raschiare i dati degli hotel da Booking.com utilizzando Python. Abbiamo sottolineato l'importanza di utilizzare intestazioni HTTP e proxy appropriati per aggirare le misure anti-scraping. I dati estratti possono essere salvati in un file CSV per ulteriori analisi. Quando si effettua lo scraping di siti web, è bene controllare sempre i termini di servizio per evitare di violarli.

Commenti:

0 Commenti