Um guia para seletores HTML para a Web Scraping

Guias, Scraping, Pitão, 08/11/20245 minutos de leitura

Os seletores de HTML são essenciais para a Web scraping, permitindo que os desenvolvedores direcionem elementos específicos em uma página da Web. Ao usar esses seletores, os desenvolvedores podem extrair dados com precisão.

A Web scraping envolve a obtenção de dados de sites navegando em sua estrutura HTML. Os seletores de HTML são cruciais, permitindo que você identifique tags, atributos ou conteúdo específicos. Seja para extrair preços de produtos ou manchetes, os seletores são seu guia.

O uso de seletores HTML simplifica efetivamente a extração de dados e reduz os erros. Eles ajudam você a se concentrar em elementos importantes, economizando tempo e esforço na coleta de insights de fontes on-line.

Neste blog, exploraremos como usar os seletores abaixo com Python e a biblioteca"Beautifulsoup":

  • Seletores de Id
  • Seletores de classe
  • Seletores de atributos
  • Seletores hierárquicos
  • Combinação desses seletores

Seletores de ID

Em HTML, os IDs são identificadores exclusivos atribuídos a elementos específicos, garantindo que não haja dois elementos com o mesmo ID. Essa exclusividade faz com que os seletores de ID sejam ideais para direcionar elementos singulares em uma página da Web. Por exemplo, se você estiver acessando scraping uma página da Web com várias seções, cada seção poderá ter seu próprio ID, permitindo que você extraia dados de uma seção específica sem interferência.

Vejamos, por exemplo este siteespecialmente o elemento abaixo <div id="pages"> ...</div>

Esse elemento contém outros elementos HTML aninhados, mas o principal é que ele é único neste site e podemos tirar proveito desse cenário, por exemplo, quando quisermos acessar scrape seções específicas do site. Nesse caso, esse elemento inclui alguns outros artigos que explicaremos com os outros seletores abaixo. Veja como é essa seção na página:

Vamos explorar um exemplo simples usando 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:

  • Enviar uma solicitação: A biblioteca de solicitações envia uma solicitação GET para obter o conteúdo HTML do URL de destino.
  • Analisar HTML: A BeautifulSoup analisa o HTML, o que nos permite pesquisar na estrutura do documento.
  • Find Specific <div>: Usamos soup.find("div", id="pages") para localizar o <div> elemento com id="páginas".
  • Conteúdo da tela: Se o <div> for encontrado, imprimimos seu conteúdo. Caso contrário, uma mensagem indica que ele está faltando.

Limitações dos seletores de ID:

Os seletores 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 consistente de dados. Nessas situações, pode ser necessário usar seletores alternativos para obter resultados confiáveis.

Seletores de classe

Os seletores de classe são flexíveis porque permitem que você direcione grupos de elementos que compartilham a mesma classe. Isso os torna essenciais para páginas da Web com elementos recorrentes. Por exemplo, um site que exibe uma lista de produtos pode atribuir a mesma classe a cada item do produto.

Vamos dar um exemplo novamente usando este site. Acima, identificamos um <div id="pages"> usando o seletor de ID e, nesse elemento div, há alguns artigos que têm a mesma classe.

Como você pode ver, temos quatro elementos com a mesma classe <div class="page">

Veja como eles aparecem no site:

No código abaixo, selecionaremos todos os elementos com a classe "page", que retornará uma lista que pode ser usada 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:

  • Enviar uma solicitação: Usamos solicitações para enviar uma solicitação GET ao URL, recuperando o conteúdo HTML da página da Web.
  • Analisar HTML com a BeautifulSoup: Se a solicitação for bem-sucedida, a BeautifulSoup analisará o HTML, o que nos permitirá pesquisar e interagir com os elementos.
  • Localizar elementos por classe: Usamos soup.find_all("div", class_="page") para localizar todos os <div> elementos com a classe "page", retornando-os como uma lista.
  • Salvar na lista: Extraímos e limpamos o conteúdo de texto de cada elemento, salvando-o em uma lista chamada pages_list.

Limitações dos seletores de classe

Ao usar seletores de classe, esteja atento a possíveis problemas, como a seleção de elementos não intencionais. Várias classes em um único elemento podem exigir filtragem adicional para obter um direcionamento preciso.

Seletores de atributos

Os seletores de atributos permitem que você direcione elementos com base na presença, no valor ou no valor parcial de atributos específicos em tags HTML. Isso é particularmente útil quando as classes ou IDs não são exclusivas ou quando você precisa filtrar elementos com atributos dinâmicos, como dados-* ou href em links.

No exemplo a seguir, selecionaremos todas as imagens na imagem página da web e extrair seus URLs de origem ou src atributos. Essa é a aparência do elemento na estrutura html e na visualização da página da Web:

No código a seguir, utilizamos o BeautifulSoup para analisar todos os <img> extraindo seus elementos src e armazenando-os em uma 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}")

Limitações dos seletores de classe

Os seletores de atributos só podem selecionar elementos com atributos estáticos, o que os torna menos eficazes para conteúdo dinâmico, como elementos carregados por JavaScript. Eles dependem de estruturas HTML estáveis, portanto, alterações frequentes no layout do site podem prejudicá-los. Além disso, eles não podem gerenciar filtragem complexa ou várias condições, o que limita sua precisão. Eles também podem pegar elementos não intencionais se atributos como classe ou nome forem compartilhados por vários elementos.

Seletores hierárquicos

Os seletores hierárquicos permitem que você direcione elementos HTML com base em sua posição e relacionamento com outros elementos na estrutura HTML. Essa abordagem é particularmente útil ao trabalhar com tabelas ou listas aninhadas, em que os dados são organizados em um formato pai-filho.

Neste exemplo, estamos usando seletores hierárquicos para scrape dados de uma tabela de estatísticas de times de hóquei encontrada em esta página da web.
A tabela contém linhas <tr> representando cada equipe, e cada linha contém células <td> com informações como nome da equipe, ano, vitórias e derrotas. Cada linha tem o class="equipe"identificando-o como uma entrada relevante em nossos dados. Ao navegar a partir da seção <table> to each <tr> and then to each <td>Com o uso do sistema, podemos capturar os dados de forma eficiente e estruturada.

Abaixo, você encontrará duas imagens para ajudá-lo a visualizar onde essa tabela está localizada na estrutura HTML e como ela aparece na página da Web real.

Agora, vamos examinar o código abaixo para ver como os seletores hierárquicos podem ser usados para extrair esses 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}")

Limitações dos seletores hierárquicos

Os seletores hierárquicos dependem da estrutura HTML, portanto, alterações no layout podem facilmente quebrar o script scraping . Eles também estão limitados ao conteúdo estático e não podem acessar elementos carregados dinamicamente pelo JavaScript. Esses seletores geralmente exigem navegação precisa por meio de relações pai-filho, o que pode ser um desafio em estruturas profundamente aninhadas. Além disso, eles podem ser ineficientes ao extrair dados dispersos, pois precisam atravessar vários níveis para chegar a elementos específicos.

Uso de seletores combinados para melhor direcionamento

Cada tipo de seletor tem uma finalidade exclusiva, e a combinação deles nos permite navegar e capturar dados com precisão a partir de conteúdo aninhado ou estruturado. Por exemplo, o uso de um seletor de ID pode ajudar a localizar a área de conteúdo principal, os seletores de classe podem isolar elementos repetidos, os seletores de atributo podem extrair links ou imagens específicos e os seletores hierárquicos podem alcançar elementos aninhados em seções específicas. Juntas, essas técnicas oferecem uma abordagem eficiente para scraping 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}")

Explicação do código

  • Seletor de ID: Começamos localizando a área de conteúdo principal com id="pages", que contém as seções de que precisamos.
  • Seletor de classe: Dentro dessa área principal, usamos class="page" para localizar cada bloco de conteúdo individual que representa uma seção de interesse.
  • Seletores hierárquicos: Em cada bloco de "página", usamos:
    • page.find("h3", class_="page-title") para encontrar o título.
    • title_tag.find("a")["href"] para recuperar o URL do link da tag âncora no título.
  • Seletor de atributos: Acessamos o atributo href de cada link para capturar os URLs exatos associados a cada seção.
  • Saída: O script imprime o título, o link e a descrição de cada seção, fornecendo uma visão estruturada dos dados extraídos da página.

Conclusão

Na Web scraping, saber como usar seletores HTML pode melhorar muito suas habilidades de extração de dados, permitindo que você colete informações importantes com precisão. Seletores como ID, classe, atributo e seletores hierárquicos têm usos específicos para diferentes tarefas scraping . scraping Ao usar essas ferramentas em conjunto, você pode lidar com uma ampla gama de desafios da Web com confiança.

Para praticar, sites como Scrape This Site e Books to Scrape oferecem ótimos exemplos para ajudá-lo a refinar suas habilidades. E se precisar de ajuda ou quiser se conectar com outras pessoas interessadas na Web scraping, fique à vontade para entrar em nosso canal do Discord em https://discord.com/invite/scrape.

Feliz scraping!