Os selectores HTML são fundamentais para a recolha de dados da Web, permitindo aos programadores visar elementos específicos de uma página Web. Ao utilizar estes selectores, os programadores podem extrair dados com precisão.
O Web scraping envolve a obtenção de dados de sítios Web através da navegação na sua estrutura HTML. Os selectores HTML são cruciais, permitindo-lhe identificar etiquetas, atributos ou conteúdos específicos. Quer se trate de extrair preços de produtos ou cabeçalhos, os selectores são o seu guia.
A utilização de selectores HTML simplifica eficazmente a extração de dados e reduz os erros. Ajudam-no a concentrar-se em elementos importantes, poupando tempo e esforço na recolha de informações de fontes online.
Neste blogue, vamos explorar a forma de utilizar os selectores abaixo com Python e a biblioteca"Beautifulsoup":
Em HTML, os IDs são identificadores únicos atribuídos a elementos específicos, assegurando que não há dois elementos que partilhem o mesmo ID. Esta exclusividade faz com que os selectores de ID sejam ideais para visar elementos singulares numa página Web. Por exemplo, se estiver a recolher uma página Web com várias secções, cada secção pode ter o seu próprio ID, permitindo-lhe extrair dados de uma secção específica sem interferência.
Vejamos, por exemplo este sítio Web, especialmente o elemento abaixo <div id="pages"> ...</div>
Este elemento contém outros elementos HTML aninhados, mas o mais importante é que este elemento é único neste sítio Web e podemos tirar partido deste cenário, por exemplo, quando quisermos extrair secções específicas do sítio Web. Neste caso, este elemento inclui alguns outros artigos que explicaremos com os outros selectores abaixo. Eis o aspeto desta secção da página:
Vamos explorar um exemplo simples utilizando as bibliotecas "requests" e "bs4" do 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}")
Explicação:
soup.find("div", id="pages")
para localizar o <div>
elemento com id="páginas"
. <div>
for encontrado, imprimimos o seu conteúdo. Se não for, uma mensagem indica que está em falta.Os selectores de ID são poderosos, mas têm limitações. As IDs dinâmicas que mudam a cada carregamento de página podem dificultar a extração de dados consistentes. Nestas situações, pode ser necessário utilizar selectores alternativos para obter resultados fiáveis.
Os selectores de classe são flexíveis porque permitem direcionar grupos de elementos que partilham a mesma classe. Isto torna-os essenciais para páginas Web com elementos recorrentes. Por exemplo, um sítio Web que apresente uma lista de produtos pode atribuir a mesma classe a cada item do produto.
Vamos dar novamente um exemplo utilizando este sítio Web. Acima identificámos um <div id="pages">
utilizando o Seletor de ID e, neste elemento div, existem alguns artigos que têm a mesma classe.
Como se pode ver, temos quatro elementos com a mesma classe <div class="page">
Eis o seu aspeto no sítio Web:
No código abaixo, seleccionaremos todos os elementos com a classe "page", que devolverá uma lista que pode ser utilizada para análise posterior.
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}")
Explicação:
soup.find_all("div", class_="page")
para localizar todos os <div>
elementos com a classe "page", devolvendo-os como uma lista. Ao utilizar selectores de classe, tenha em atenção potenciais problemas, como a seleção de elementos não pretendidos. Múltiplas classes num único elemento podem exigir uma filtragem adicional para obter uma seleção precisa.
Os selectores de atributos permitem-lhe direcionar elementos com base na presença, valor ou valor parcial de atributos específicos em etiquetas HTML. Isto é particularmente útil quando as classes ou IDs não são únicas ou quando é necessário filtrar elementos com atributos dinâmicos, tais como dados-*
ou href
valores nas ligações.
No exemplo seguinte, seleccionaremos todas as imagens neste página web e extrair os seus URLs de origem ou src
atributos. Este é o aspeto do elemento na estrutura html e na visualização da página web:
No código a seguir, utilizamos o BeautifulSoup para analisar todos os <img> elementos, extraindo os seus src
e armazenando-os numa lista.
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}")
Os selectores de atributos só podem selecionar elementos com atributos estáticos, o que os torna menos eficazes para conteúdos dinâmicos, como elementos carregados através de JavaScript. Dependem de estruturas HTML estáveis, pelo que alterações frequentes da disposição do sítio Web podem perturbá-los. Além disso, não podem gerir filtros complexos ou condições múltiplas, o que limita a sua precisão. Podem também detetar elementos não pretendidos se atributos como classe ou nome forem partilhados por vários elementos.
Os selectores hierárquicos permitem-lhe selecionar elementos HTML com base na sua posição e relação com outros elementos na estrutura HTML. Esta abordagem é particularmente útil quando se trabalha com tabelas ou listas aninhadas, em que os dados são organizados num formato pai-filho.
Neste exemplo, estamos a utilizar selectores hierárquicos para extrair dados de uma tabela de estatísticas de equipas de hóquei encontrada em esta página web.
A tabela contém linhas <tr>
representando cada equipa, e cada linha contém células <td>
com informações como o nome da equipa, o ano, as vitórias e as derrotas. Cada linha tem o class="equipa"
identificando-o como uma entrada relevante nos nossos dados. Ao navegar a partir do <table>
to each <tr> and then to each <td>
Se o utilizador tiver uma visão geral dos dados, pode capturá-los de forma eficiente e estruturada.
Abaixo, encontrará duas imagens para o ajudar a visualizar onde esta tabela está localizada na estrutura HTML e como aparece na página Web real.
Agora, vejamos o código abaixo para ver como os selectores hierárquicos podem ser utilizados para extrair estes dados:
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}")
Os selectores hierárquicos dependem da estrutura HTML, pelo que as alterações na disposição podem facilmente interromper o script de exploração. Estão também limitados a conteúdo estático e não podem aceder a elementos carregados dinamicamente por JavaScript. Estes selectores requerem frequentemente uma navegação precisa através de relações pai-filho, o que pode ser um desafio em estruturas profundamente aninhadas. Além disso, podem ser ineficientes na extração de dados dispersos, uma vez que têm de atravessar vários níveis para chegar a elementos específicos.
Cada tipo de seletor tem uma finalidade única, e a sua combinação permite-nos navegar e capturar dados com precisão a partir de conteúdo aninhado ou estruturado. Por exemplo, a utilização de um seletor de ID pode ajudar a localizar a área de conteúdo principal, os selectores de classe podem isolar elementos repetidos, os selectores de atributo podem extrair ligações ou imagens específicas e os selectores hierárquicos podem alcançar elementos aninhados em secções específicas. Em conjunto, estas técnicas proporcionam uma abordagem poderosa para a recolha de dados estruturados.
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="página"
para encontrar cada bloco de conteúdo individual que representa uma secção de interesse. page.find("h3", class_="page-title")
para encontrar o título. title_tag.find("a")["href"]
para obter o URL da ligação a partir da etiqueta de âncora no título. Na recolha de dados da Web, saber como utilizar selectores HTML pode melhorar significativamente as suas capacidades de extração de dados, permitindo-lhe recolher informações importantes com precisão. Seletores como ID, classe, atributo e seletores hierárquicos têm utilizações específicas para diferentes tarefas de recolha de dados. Ao utilizar estas ferramentas em conjunto, pode lidar com uma vasta gama de desafios de recolha de dados da Web com confiança.
Para praticar, sites como Scrape This Site e Books to Scrape oferecem excelentes exemplos para o ajudar a aperfeiçoar as suas capacidades. E se precisar de ajuda ou quiser se conectar com outras pessoas interessadas em raspagem da Web, sinta-se à vontade para participar do nosso canal do Discord em https://discord.com/invite/scrape.
Boa raspagem!