Come raschiare Yelp usando Python

Commenti: 0

Lo scraping di dati da Yelp può fornire preziose informazioni sui ristoranti locali, compresi dettagli come il nome, l'URL, le cucine e le valutazioni. Utilizzando le librerie request e lxml di Python, questo tutorial mostrerà come effettuare lo scraping dei risultati di ricerca di Yelp. Verranno trattate diverse tecniche, tra cui l'uso di proxy, la gestione delle intestazioni e l'estrazione dei dati con XPath.

Fase 1: Impostazione dell'ambiente

Prima di iniziare il processo di scraping, assicuratevi di avere installato Python e le librerie necessarie:

pip install requests
pip install lxml

Queste librerie ci aiuteranno a inviare richieste HTTP a Yelp, ad analizzare il contenuto HTML e a estrarre i dati di cui abbiamo bisogno.

Fase 2: invio di una richiesta a Yelp

Per prima cosa, dobbiamo inviare una richiesta GET alla pagina dei risultati di ricerca di Yelp per recuperare il contenuto HTML. Ecco come fare:

import requests

# URL della pagina di ricerca Yelp
url = "https://www.yelp.com/search?find_desc=restaurants&find_loc=San+Francisco%2C+CA"

# Inviare una richiesta GET per recuperare il contenuto HTML
response = requests.get(url)

# Controllare se la richiesta è andata a buon fine
if response.status_code == 200:
    print("Successfully fetched the page content")
else:
    print("Failed to retrieve the page content")

Comprendere le intestazioni HTTP

Quando si effettuano richieste a un sito web, è essenziale includere le intestazioni HTTP appropriate. Le intestazioni possono contenere metadati sulla richiesta, come l'agente utente, che identifica il browser o lo strumento che effettua la richiesta. L'inclusione di queste intestazioni può aiutare a evitare il blocco o il throttling da parte del sito web di destinazione.

Ecco come impostare le intestazioni:

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': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
    '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/127.0.0.0 Safari/537.36',
}

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

Implementazione della rotazione proxy

Quando si effettua lo scraping di un grande volume di pagine, c'è il rischio che il proprio indirizzo IP venga bloccato dal sito di destinazione. Per evitare che ciò accada, si raccomanda l'uso di server proxy. Per questa guida, è consigliabile utilizzare server proxy dinamici con rotazione automatica. In questo modo, è sufficiente configurare le impostazioni del server proxy una sola volta e la rotazione aiuterà a mantenere l'accesso cambiando periodicamente l'indirizzo IP, riducendo la probabilità di essere bloccati.

proxies = {
    'http': 'http://username:password@proxy-server:port',
    'https': 'https://username:password@proxy-server:port'
}

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

Fase 3: analizzare il contenuto HTML con lxml

Una volta ottenuto il contenuto HTML, il passo successivo è analizzarlo ed estrarre i dati rilevanti. A questo scopo utilizzeremo la libreria lxml.

from lxml import html

# Analizzare il contenuto HTML utilizzando lxml
parser = html.fromstring(response.content)

Identificazione degli elementi da raschiare

È necessario individuare i singoli elenchi di ristoranti nella pagina dei risultati della ricerca. Questi elementi possono essere identificati usando le espressioni XPath. Per Yelp, gli elenchi sono solitamente racchiusi in un elemento div con un attributo specifico data-test.

# Estrarre i singoli elementi del ristorante
elements = parser.xpath('//div[@data-testid="serp-ia-card"]')[2:-1]

Utilizzo di XPath per l'estrazione dei dati

XPath è un potente strumento per la navigazione e la selezione di nodi da un documento HTML. In questa esercitazione, utilizzeremo le espressioni XPath per estrarre il nome del ristorante, l'URL, le cucine e la valutazione da ciascun elemento del ristorante.

Ecco gli XPath specifici per ogni punto di dati:

  1. Nome del ristorante: .//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/text()
  2. URL del ristorante: .//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/@href
  3. Cucina: .//div[@class="priceCategory__09f24___4Wsg iaPriceCategory__09f24__x9YrM y-css-2hdccn"]/div/div/div/a/button/span/text()
  4. Valutazione: .//div[@class="y-css-9tnml4"]/@aria-label

Fase 4: Estrazione dei dati da ciascun annuncio di ristorante

Ora che abbiamo il contenuto HTML e abbiamo gestito il potenziale blocco dell'IP, possiamo estrarre i dati necessari da ciascun elenco di ristoranti.

restaurants_data = []

# Iterare su ogni elemento del ristorante
for element in elements:
    # Estrarre il nome del ristorante
    name = element.xpath('.//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/text()')[0]

    # Estrarre l'URL del ristorante
    url = element.xpath('.//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/@href')[0]

    # Estrarre le cucine
    cuisines = element.xpath('.//div[@class="priceCategory__09f24___4Wsg iaPriceCategory__09f24__x9YrM y-css-2hdccn"]/div/div/div/a/button/span/text()')

    # Estrarre la valutazione
    rating = element.xpath('.//div[@class="y-css-9tnml4"]/@aria-label')[0]

    # Creare un dizionario per memorizzare i dati
    restaurant_info = {
        "name": name,
        "url": url,
        "cuisines": cuisines,
        "rating": rating
    }

    # Aggiungere le informazioni sul ristorante all'elenco
    restaurants_data.append(restaurant_info)

Fase 5: Salvare i dati come JSON

Dopo aver estratto i dati, è necessario salvarli in un formato strutturato. JSON è un formato molto utilizzato a questo scopo.

import json

# Salvare i dati in un file JSON
with open('yelp_restaurants.json', 'w') as f:
    json.dump(restaurants_data, f, indent=4)

print("Data extraction complete. Saved to yelp_restaurants.json")

Codice completo

import requests
from lxml import html
import json

# URL della pagina di ricerca Yelp
url = "https://www.yelp.com/search?find_desc=restaurants&find_loc=San+Francisco%2C+CA"

# Impostare le intestazioni per simulare una richiesta del browser
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
    'Accept-Language': 'en-US,en;q=0.5'
}

# Impostare i proxy, se necessario
proxies = {
    'http': 'http://username:password@proxy-server:port',
    'https': 'https://username:password@proxy-server:port'
}

# Inviare una richiesta GET per recuperare il contenuto HTML
response = requests.get(url, headers=headers, proxies=proxies)

# Controllare se la richiesta è andata a buon fine
if response.status_code == 200:
    print("Successfully fetched the page content")
else:
    print("Failed to retrieve the page content")

# Analizzare il contenuto HTML utilizzando lxml
parser = html.fromstring(response.content)

# Estrarre i singoli elementi del ristorante
elements = parser.xpath('//div[@data-testid="serp-ia-card"]')[2:-1]

# Inizializzare un elenco per contenere i dati estratti
restaurants_data = []

# Iterare su ogni elemento del ristorante
for element in elements:
    # Estrarre il nome del ristorante
    name = element.xpath('.//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/text()')[0]

    # Estrarre l'URL del ristorante
    url = element.xpath('.//div[@class="businessName__09f24__HG_pC y-css-ohs7lg"]/div/h3/a/@href')[0]

    #  Estrarre le cucine
    cuisines = element.xpath('.//div[@class="priceCategory__09f24___4Wsg iaPriceCategory__09f24__x9YrM y-css-2hdccn"]/div/div/div/a/button/span/text()')

    # Estrarre la valutazione
    rating = element.xpath('.//div[@class="y-css-9tnml4"]/@aria-label')[0]

    # Creare un dizionario per memorizzare i dati
    restaurant_info = {
        "name": name,
        "url": url,
        "cuisines": cuisines,
        "rating": rating
    }

    # Aggiungere le informazioni sul ristorante all'elenco
    restaurants_data.append(restaurant_info)

# Salvare i dati in un file JSON
with open('yelp_restaurants.json', 'w') as f:
    json.dump(restaurants_data, f, indent=4)

print("Data extraction complete. Saved to yelp_restaurants.json")

È fondamentale che gli utenti configurino correttamente le intestazioni HTTP e utilizzino i proxy per aggirare le restrizioni ed evitare il blocco. Per un'esperienza di scraping ottimizzata e più sicura, considerate la possibilità di automatizzare la rotazione degli IP. L'utilizzo di proxy dinamici residenziali o mobili può migliorare notevolmente questo processo, riducendo la probabilità di essere individuati e bloccati.

Commenti:

0 Commenti