I selettori HTML sono fondamentali per il web scraping e consentono agli sviluppatori di puntare su elementi specifici di una pagina web. Utilizzando questi selettori, gli sviluppatori possono estrarre i dati in modo preciso.
Il web scraping consiste nell'ottenere dati dai siti web navigando nella loro struttura HTML. I selettori HTML sono fondamentali e consentono di individuare tag, attributi o contenuti specifici. Che si tratti di estrarre i prezzi dei prodotti o i titoli dei giornali, i selettori sono la vostra guida.
L'uso dei selettori HTML ottimizza l'estrazione dei dati e riduce gli errori. Permettono di concentrarsi sugli elementi importanti, risparmiando tempo e fatica nella raccolta di informazioni dalle fonti online.
In questo blog esploreremo come utilizzare i selettori sottostanti con Python e la libreria"Beautifulsoup":
In HTML, gli ID sono identificatori unici assegnati a elementi specifici, che garantiscono che non ci siano due elementi che condividono lo stesso ID. Questa unicità rende i selettori ID ideali per individuare singoli elementi di una pagina web. Ad esempio, se si sta effettuando lo scraping di una pagina web con più sezioni, ogni sezione può avere il proprio ID, consentendo di estrarre i dati da una particolare sezione senza interferenze.
Prendiamo ad esempio questo sito web, in particolare l'elemento sottostante <div id="pages"> ...</div>
Questo elemento contiene altri elementi HTML annidati, ma la cosa principale è che questo elemento è unico in questo sito web e possiamo sfruttare questo scenario, ad esempio quando vogliamo fare lo scraping di particolari sezioni del sito. In questo caso, questo elemento include alcuni altri articoli che spiegheremo con gli altri selettori di seguito. Ecco come appare questa sezione della pagina:
Esaminiamo un esempio semplice utilizzando le librerie "requests" e "bs4" di Python:
import requests
from bs4 import BeautifulSoup
# Step 1: Send a GET request to the website
url = "https://www.scrapethissite.com/pages/"
response = requests.get(url)
if response.status_code == 200:
# Step 2: Parse the HTML content with BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
# Step 3: Find the div with id="pages"
pages_div = soup.find("div", id="pages")
# Step 4: Display the content or handle it as needed
if pages_div:
print("Content of the div with id='pages':")
print(pages_div.text.strip())
else:
print("No div with id='pages' found.")
else:
print(f"Failed to retrieve the webpage. Status code: {response.status_code}")
Spiegazione:
soup.find("div", id="pages")
per individuare il <div>
con id="pagine"
. <div>
viene trovato, viene stampato il suo contenuto. In caso contrario, un messaggio indica che manca.I selettori di ID sono potenti, ma hanno dei limiti. Gli ID dinamici che cambiano a ogni caricamento della pagina possono rendere difficile l'estrazione coerente dei dati. In queste situazioni, per ottenere risultati affidabili può essere necessario utilizzare selettori alternativi.
I selettori di classe sono flessibili perché consentono di indirizzare gruppi di elementi che condividono la stessa classe. Questo li rende essenziali per le pagine web con elementi ricorrenti. Per esempio, un sito web che mostra un elenco di prodotti può assegnare la stessa classe a ogni elemento del prodotto.
Facciamo un altro esempio utilizzando questo sito web. Sopra abbiamo identificato un <div id="pages">
utilizzando il selettore ID e in questo elemento div ci sono alcuni articoli che hanno la stessa classe.
Come si può vedere, abbiamo quattro elementi con la stessa classe <div class="page">
Ecco come appaiono sul sito web:
Nel codice sottostante, selezioneremo tutti gli elementi con la classe "page", restituendo un elenco che potrà essere utilizzato per un ulteriore parsing.
import requests
from bs4 import BeautifulSoup
# Step 1: Send a GET request to the website
url = "https://www.scrapethissite.com/pages/"
response = requests.get(url)
if response.status_code == 200:
# Step 2: Parse the HTML content with BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
# Step 3: Find all elements with class="page"
page_elements = soup.find_all("div", class_="page")
# Step 4: Save each element's text content in a list
pages_list = [page.text.strip() for page in page_elements]
print("Content of elements with class 'page':")
for i, page in enumerate(pages_list, start=1):
print(f"Page {i}:")
print(page)
print("-" * 20)
else:
print(f"Failed to retrieve the webpage. Status code: {response.status_code}")
Spiegazione:
soup.find_all("div", class_="page")
per individuare tutti i <div>
elementi con la classe "page", restituendoli come elenco. Quando si usano i selettori di classe, occorre prestare attenzione a potenziali problemi, come la selezione di elementi non voluti. Più classi su un singolo elemento possono richiedere un filtraggio aggiuntivo per ottenere un targeting accurato.
I selettori di attributi consentono di indirizzare gli elementi in base alla presenza, al valore o al valore parziale di attributi specifici all'interno dei tag HTML. Questo è particolarmente utile quando le classi o gli ID non sono univoci o quando è necessario filtrare elementi con attributi dinamici, come ad esempio dati-*
o href
nei collegamenti.
Nell'esempio seguente, si selezioneranno tutte le immagini presenti in questo file pagina web ed estrarre i loro URL di origine o src
attributi. Questo è l'aspetto dell'elemento nella struttura html e nella visualizzazione della pagina web:
Nel codice che segue, utilizziamo BeautifulSoup per analizzare tutti i file <img> elementi, estraendo i loro src
e memorizzarli in un elenco.
import requests
from bs4 import BeautifulSoup
# Step 1: Send a GET request to the website
url = "https://www.scrapethissite.com/pages/frames/"
response = requests.get(url)
if response.status_code == 200:
# Step 2: Parse the HTML content with BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
# Step 3: Find all <img> elements with a 'src' attribute
image_elements = soup.find_all("img", src=True)
# Step 4: Save the 'src' attributes in a list
images_list = [img['src'] for img in image_elements]
print("Image sources found on the page:")
for i, src in enumerate(images_list, start=1):
print(f"Image {i}: {src}")
else:
print(f"Failed to retrieve the webpage. Status code: {response.status_code}")
I selettori di attributi possono selezionare solo elementi con attributi statici, il che li rende meno efficaci per i contenuti dinamici, come gli elementi caricati tramite JavaScript. Dipendono da strutture HTML stabili, quindi le frequenti modifiche al layout del sito web possono disturbarli. Inoltre, non possono gestire filtri complessi o condizioni multiple, il che limita la loro precisione. Potrebbero anche rilevare elementi non voluti, se attributi come classe o nome sono condivisi da più elementi.
I selettori gerarchici consentono di indirizzare gli elementi HTML in base alla loro posizione e alla loro relazione con altri elementi della struttura HTML. Questo approccio è particolarmente utile quando si lavora con tabelle o elenchi annidati, dove i dati sono organizzati in un formato genitore-figlio.
In questo esempio, si utilizzano selettori gerarchici per raschiare i dati da una tabella di statistiche di squadre di hockey che si trova su questa pagina web.
La tabella contiene righe <tr>
che rappresentano ogni squadra, e ogni riga contiene celle <td>
con informazioni quali il nome della squadra, l'anno, le vittorie e le sconfitte. Ogni riga contiene il class="squadra"
identificandola come una voce rilevante nei nostri dati. Navigando dalla pagina <table>
to each <tr> and then to each <td>
Possiamo acquisire i dati in modo efficiente e strutturato.
Di seguito sono riportate due immagini che aiutano a visualizzare la posizione di questa tabella nella struttura HTML e il modo in cui appare nella pagina web.
Vediamo ora il codice sottostante per capire come si possono usare i selettori gerarchici per estrarre questi dati:
import requests
from bs4 import BeautifulSoup
url = "https://www.scrapethissite.com/pages/forms/"
# Step 1: Send a GET request to the website
response = requests.get(url)
if response.status_code == 200:
# Step 2: Parse the HTML content with BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
# Step 3: Find all rows in the table with class="team"
teams_data = []
team_rows = soup.find_all("tr", class_="team")
# Step 4: Extract and store each team's data
for row in team_rows:
team = {
"name": row.find("td", class_="name").text.strip(),
"year": row.find("td", class_="year").text.strip(),
"wins": row.find("td", class_="wins").text.strip(),
"losses": row.find("td", class_="losses").text.strip(),
"ot_losses": row.find("td", class_="ot-losses").text.strip(),
"win_pct": row.find("td", class_="pct").text.strip(),
"goals_for": row.find("td", class_="gf").text.strip(),
"goals_against": row.find("td", class_="ga").text.strip(),
"goal_diff": row.find("td", class_="diff").text.strip(),
}
teams_data.append(team)
# Step 5: Display the extracted data
for team in teams_data:
print(team)
else:
print(f"Failed to retrieve the webpage. Status code: {response.status_code}")
I selettori gerarchici dipendono dalla struttura dell'HTML, quindi le modifiche al layout possono facilmente interrompere lo script di scraping. Inoltre, sono limitati ai contenuti statici e non possono accedere agli elementi caricati dinamicamente da JavaScript. Questi selettori spesso richiedono una navigazione precisa attraverso le relazioni genitore-figlio, il che può essere difficile in strutture profondamente annidate. Inoltre, possono essere inefficienti quando si tratta di estrarre dati sparsi, poiché devono attraversare più livelli per raggiungere elementi specifici.
Ogni tipo di selettore ha uno scopo unico e la loro combinazione ci permette di navigare e catturare i dati con precisione da contenuti annidati o strutturati. Ad esempio, l'uso di un selettore ID può aiutare a localizzare l'area principale del contenuto, i selettori di classe possono isolare elementi ripetuti, i selettori di attributo possono estrarre collegamenti o immagini specifiche e i selettori gerarchici possono raggiungere elementi annidati all'interno di sezioni specifiche. L'insieme di queste tecniche fornisce un approccio potente per lo scraping di dati strutturati.
import requests
from bs4 import BeautifulSoup
# Target URL
url = "https://www.scrapethissite.com/pages/"
response = requests.get(url)
if response.status_code == 200:
# Step 2: Parse the HTML content with BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
# Use ID selector to find the main content
main_content = soup.find(id="pages")
# Use class selector to find each "page" section
pages = main_content.find_all("div", class_="page") if main_content else []
# Extract details from each "page" section using hierarchical selectors
for page in pages:
# Use hierarchical selector to find title link and URL within each "page"
title_tag = page.find("h3", class_="page-title")
title = title_tag.text.strip() if title_tag else "No Title"
link = title_tag.find("a")["href"] if title_tag and title_tag.find("a") else "No Link"
# Use class selector to find the description
description = page.find("p", class_="lead session-desc").text.strip() if page.find("p", class_="lead session-desc") else "No Description"
print(f"Title: {title}")
print(f"Link: {link}")
print(f"Description: {description}")
print("-" * 40)
else:
print(f"Failed to retrieve the webpage. Status code: {response.status_code}")
class="pagina"
per trovare ogni singolo blocco di contenuto che rappresenta una sezione di interesse. page.find("h3", class_="page-title")
per trovare il titolo. title_tag.find("a")["href"]
per recuperare l'URL del collegamento dal tag di ancoraggio nel titolo. Nel web scraping, sapere come usare i selettori HTML può migliorare notevolmente le vostre capacità di estrazione dei dati, consentendovi di raccogliere informazioni importanti in modo accurato. Selettori come ID, classe, attributo e selettori gerarchici hanno ciascuno un uso specifico per diverse attività di scraping. Utilizzando questi strumenti insieme, è possibile gestire con sicurezza un'ampia gamma di sfide di scraping del Web.
Per fare pratica, siti come Scrape This Site e Books to Scrape offrono ottimi esempi per aiutarvi a perfezionare le vostre abilità. Se avete bisogno di aiuto o volete entrare in contatto con altri interessati al web scraping, non esitate a unirvi al nostro canale Discord all'indirizzo https://discord.com/invite/scrape.
Buona raschiatura!