Tutorial de Scraping de Dados em HTML

Descubra como dominar o scraping de dados em HTML para coletar dados de sites de forma eficiente, ideal para aprimorar seus projetos e estratégias.
17 min de leitura
HTML web scraping main blog image

Se você tem interesse em scraping de dados, entender HTML é fundamental porque todos os sites são construídos com ele. O scraping de dados pode ser usado em diversos cenários e pode ajudar a coletar dados de sites sem APIs, monitorar preços de produtos, criar listas de leads, realizar pesquisas acadêmicas e muito mais.

Neste artigo, você aprenderá os fundamentos do HTML e como extrair, fazer parsing e processar dados usando Python.

Interessado em um guia aprofundado de scraping de dados com Python? Clique aqui.

Como Fazer Scraping de Sites e Extrair HTML

Antes de começar este tutorial, vamos revisar os componentes essenciais do HTML.

Introdução ao HTML

HTML é uma coleção de tags que informam ao navegador sobre a estrutura e os elementos de um site. Por exemplo, <h1> Text </h1> indica ao navegador que o trecho de texto após a tag é um título, e <a href=""> link </a> identifica um hiperlink.

Um atributo HTML fornece informações adicionais sobre uma tag. Por exemplo, o atributo href da tag <a> </a> fornece informações sobre a URL da página para a qual o atributo aponta.

Classes e IDs são atributos essenciais para identificar com precisão elementos em uma página. As classes agrupam elementos semelhantes para estilizá-los de forma consistente com CSS ou manipulá-los uniformemente com JavaScript. As classes são selecionadas usando .class-name.

No site W3Schools, os grupos de classes têm esta aparência:

<div class="city">
  <h2>London</h2>
  <p>London is the capital of England.</p>
</div>

<div class="city">
  <h2>Paris</h2>
  <p>Paris is the capital of France.</p>
</div>

<div class="city">
  <h2>Tokyo</h2>
  <p>Tokyo is the capital of Japan.</p>
</div>

Você pode ver como cada título e bloco de cidade está envolto por um div que tem a mesma classe city.

Em contraste, os IDs são únicos para cada elemento (ou seja, dois elementos não podem ter o mesmo ID). Por exemplo, os seguintes H1s têm IDs únicos e podem ser estilizados/manipulados de forma exclusiva:

<h1 id="header1">Hello World!</h1>

<h1 id="header2">Lorem Ipsum Dolor</h1>

A sintaxe para selecionar elementos com IDs é #id-name.

Agora que você conhece os fundamentos do HTML, vamos começar o scraping de dados.

Configure Seu Ambiente de Scraping

Este tutorial utiliza Python, pois oferece diversas bibliotecas de scraping HTML e a linguagem é fácil de aprender. Para verificar se o Python está instalado no seu computador, execute o seguinte comando no PowerShell (Windows) ou no terminal (macOS):

python3

Se o Python estiver instalado, você verá o número da versão; caso contrário, receberá um erro. Vá em frente e instale o Python se ainda não o tiver.

Em seguida, crie uma pasta chamada WebScraper e crie um arquivo dentro dela chamado scraper.py. Depois, abra-o no ambiente de desenvolvimento integrado (IDE) de sua preferência. Visual Studio Code é utilizado aqui:

Uma imagem mostrando onde o VSC é usado

Um IDE é uma aplicação multifuncional que permite aos programadores escrever código, depurá-lo, testar programas, criar automações e muito mais. Você o usará aqui para codificar seu scraper HTML.

Em seguida, você precisa separar sua instalação global do Python do seu projeto de scraping criando um ambiente virtual. Isso ajuda a evitar conflitos de dependências e mantém toda a aplicação organizada.

Para isso, instale a biblioteca virtualenv usando o seguinte comando:

pip3 install virtualenv

Navegue até a pasta do seu projeto:

cd WebScraper

Em seguida, crie um ambiente virtual:

 python<version> -m venv <virtual-environment-name>

Este comando cria uma pasta para todos os pacotes e scripts dentro da pasta do seu projeto:

Comando para criar uma pasta para todos os pacotes e scripts

Agora, você precisa ativar o ambiente virtual usando um dos seguintes comandos (de acordo com sua plataforma):

source <virtual-environment-name>/bin/activate #In MacOS and Linux

<virtual-environment-name>/Scripts/activate.bat #In CMD

<virtual-environment-name>/Scripts/Activate.ps1 #In Powershell

Após a ativação bem-sucedida, você verá o nome do seu ambiente virtual no lado esquerdo da tela:

O nome do seu ambiente virtual

Agora que seu ambiente virtual está ativado, você precisa instalar uma biblioteca de scraping de dados. Existem diversas opções, incluindo PlaywrightSeleniumBeautiful Soup e Scrapy. Aqui, utilizamos o Playwright por ser fácil de usar, suportar múltiplos navegadores, lidar com conteúdo dinâmico e oferecer um modo headless (scraping sem interface gráfica do usuário (GUI)).

Execute pip install pytest-playwright para instalar o Playwright; em seguida, instale os navegadores necessários com playwright install.

Após instalar o Playwright, você está pronto para começar o scraping de dados.

Extrair HTML de um Site

O primeiro passo de qualquer projeto de scraping de dados é identificar o site que você deseja raspar. Aqui, utilizamos este site de teste.

Em seguida, você precisa identificar as informações que deseja extrair da página. Neste caso, é o conteúdo HTML completo da página.

Depois de identificar as informações que deseja extrair, você pode começar a codificar o scraper. Em Python, o primeiro passo é importar as bibliotecas necessárias para o Playwright. O Playwright permite importar dois tipos de APIs: sync e async. A biblioteca async é usada apenas ao escrever código assíncrono, portanto, importe a biblioteca sync com o seguinte comando:

from playwright.sync_api import sync_playwright

Após importar a biblioteca sync, você precisa declarar uma função Python usando o seguinte trecho de código:

def main():
    #Rest of the code will be inside this function

Como você pode ver na nota anterior, você escreve seu código de scraping de dados dentro desta função.

Normalmente, para obter informações de um site, você abriria um navegador, criaria uma nova aba e visitaria esse site. Para fazer o scraping do site, você precisa traduzir essas ações em código, e é para isso que você usará o Playwright. A documentação mostra que você pode chamar a sync_api importada anteriormente e abrir um navegador com este trecho:

with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)

Ao adicionar headless=False dentro dos parênteses, você consegue visualizar o conteúdo do site.

Após abrir o navegador, abra uma nova aba e visite a URL de destino:

page = browser.new_page()
try:
  page.goto("https://webscraper.io/test-sites/e-commerce/static")
except:
  print("Error")

Nota: As linhas anteriores precisam ser adicionadas após as linhas que inicializaram o navegador. Todo esse código vai dentro da função main e dentro de um único arquivo.

Este trecho de código envolve a função goto() dentro de um bloco try-except para um melhor tratamento de erros.

Quando você insere a URL de um site na barra de pesquisa, precisa aguardar o carregamento. Para simular isso no código, você pode usar o seguinte:

page.wait_for_timeout(7000) #millisecond value in brackets

Nota: Essas linhas precisam ser adicionadas após as linhas anteriores.

Por fim, é hora de extrair todo o conteúdo HTML da página usando esta linha de código:

print(page.content())

O código completo para extrair o HTML de uma página tem esta aparência:


from playwright.sync_api import sync_playwright

def main():
  with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)   
        page = browser.new_page()
        try:
            page.goto("https://webscraper.io/test-sites/e-commerce/static")
        except:
            print("Error")

        page.wait_for_timeout(7000)
        print(page.content())

main()

No Visual Studio Code, o HTML extraído tem esta aparência:

O HTML extraído no VSC

Extrair HTML Usando Atributos Específicos

Anteriormente, você extraiu todos os elementos da página do Web Scraper; no entanto, o scraping de dados só é útil quando você se limita a extrair apenas as informações necessárias. Nesta seção, você extrai apenas os títulos de todos os laptops na primeira página do site:

Mostrando os títulos que vamos extrair do site de destino

Para extrair elementos específicos, você precisa entender a estrutura do site de destino. Você pode fazer isso clicando com o botão direito e selecionando a opção Inspecionar desta forma:

Clique em inspecionar no site de destino

Alternativamente, você pode usar estes atalhos de teclado:

  • Para macOS, use Cmd + Option + I
  • Para Windows, use Control + Shift + C

Aqui está a estrutura da página de destino:

A estrutura HTML do site de destino

Você pode visualizar o código de um item específico em uma página usando a ferramenta de seleção no canto superior esquerdo da janela Inspecionar:

Como inspecionar itens específicos no código-fonte

Selecione um dos títulos de laptops na janela Inspecionar:

Inspecionando um dos títulos que queremos extrair

Você pode ver que o título está dentro de uma tag <a> </a>, que está envolta por uma tag h4, e o link tem a classe title. Isso significa que você está procurando por tags <a href> (URLs) dentro de tags <h4> que possuem a classe title.

Para criar um programa de scraping que selecione com precisão esses elementos, você precisa importar as bibliotecas para criar uma função Python, iniciar o navegador e navegar até o site de destino:

from playwright.sync_api import sync_playwright

def main():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        try:
            page.goto("https://webscraper.io/test-sites/e-commerce/static/computers/laptops")

        except:
            print("Error")

        page.wait_for_timeout(7000)

Observe que a URL de destino dentro da função page.goto() foi atualizada para apontar para a primeira página que contém a lista de laptops.

Depois de criar o programa de scraping, você precisa localizar o elemento de destino com base na análise da estrutura do site. O Playwright possui uma ferramenta chamada locators que permite localizar elementos em uma página com base em vários atributos, como os seguintes:

  • get_by_label() localiza o elemento de destino usando o rótulo associado a um elemento.
  • get_by_text() localiza o elemento de destino usando o texto que o elemento contém.
  • get_by_alt_text() localiza o elemento de destino e realiza ações em imagens usando seu texto alternativo.
  • get_by_test_id() localiza o elemento de destino usando o ID de teste de um elemento.

Você pode consultar a documentação oficial para mais métodos de localização de elementos.

Para extrair todos os títulos de laptops, você precisa localizar as tags <h4>, pois elas envolvem todos os títulos de laptops. Você pode usar o locator get_by_role() para encontrar elementos com base em sua função, como botões, caixas de seleção e títulos. Isso significa que, para encontrar todos os títulos na página, você precisa escrever o seguinte:

titles = page.get_by_role("heading").all()

Depois disso, você pode imprimi-lo no console com o seguinte código:

print(titles)

Após a impressão, você notará que ele retorna um array de elementos:

Array de elementos após imprimir os títulos

Esta saída não inclui os títulos, mas faz referência aos elementos que correspondem às condições do seletor. Você deve percorrer esses elementos para encontrar uma tag <a> com a classe title e o texto dentro dela.

Recomenda-se usar o locator CSS para encontrar um elemento com base em seu caminho e classe, e você pode usar a função all_inner_texts() para extrair o texto interno de um elemento desta forma:

for title in titles:
  laptop = title.locator("a.title").all_inner_texts()

Ao executar este código, sua saída deve ter esta aparência:

Uma imagem de como a saída deve parecer

Para rejeitar arrays sem valores, escreva o seguinte:

if len(laptop) == 1:
  print(laptop[0])

Depois de rejeitar arrays sem valores, você construiu com sucesso um programa de scraping que extrai apenas elementos específicos.

Aqui está o código completo para este scraper:

from playwright.sync_api import sync_playwright

def main():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        try:
            page.goto("https://webscraper.io/test-sites/e-commerce/static/computers/laptops")

        except:
            print("Error")

        page.wait_for_timeout(7000)

        titles = page.get_by_role("heading").all()

        for title in titles:
            laptop = title.locator("a.title").all_inner_texts()
            if len(laptop) == 1:
                print(laptop[0])

main()

Interagir com Elementos

Vamos elevar o nível agora e construir um programa que extrai os títulos da primeira página contendo laptops, navega para a segunda página e extrai esses títulos também.

Como você já sabe como extrair títulos de uma página, você só precisa descobrir como navegar para a próxima página de laptops.

Você já deve ter notado os botões de Paginação na página em que você está.

Você deve localizar o 2 e clicar nele usando seu programa de scraping. Ao inspecionar a página, você verá que o elemento necessário é um elemento de lista (tag <li>) e tem o texto interno 2:

O elemento necessário tem um texto interno de 2

Isso significa que você pode usar o seletor get_by_role() para encontrar um item de lista e um seletor get_by_text() para encontrar um elemento com 2 como texto.

Veja como codificá-lo no seu arquivo:

page.get_by_role("listitem").get_by_text("2", exact=True)

Isso encontra um elemento que corresponde a duas condições: primeiro, deve ser um item de lista e, segundo, deve ter 2 como texto.

exact=True é um argumento de função para encontrar o elemento com o texto fornecido.

Para clicar no botão, altere o código anterior para que fique assim:

        page.get_by_role("listitem").get_by_text("2", exact=True).click()

Neste código, a função click() clica no elemento fornecido.

Aguarde o carregamento da página e extraia todos os títulos novamente:

        page.wait_for_timeout(5000)

        titles = page.get_by_role("heading").all()

        for title in titles:
            laptop = title.locator("a.title").all_inner_texts()
            if len(laptop) == 1:
                print(laptop[0])

Seu bloco de código completo deve ter esta aparência:

from playwright.sync_api import sync_playwright

def main():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        try:
            page.goto("https://webscraper.io/test-sites/e-commerce/static/computers/laptops")

        except:
            print("Error")

        page.wait_for_timeout(7000)

        titles = page.get_by_role("heading").all()

        for title in titles:
            laptop = title.locator("a.title").all_inner_texts()
            if len(laptop) == 1:
                print(laptop[0])
        
        page.get_by_role("listitem").get_by_text("2", exact=True).click()

        page.wait_for_timeout(5000)

        titles = page.get_by_role("heading").all()

        for title in titles:
            laptop = title.locator("a.title").all_inner_texts()
            if len(laptop) == 1:
                print(laptop[0])

main()

Extrair HTML e Gravá-lo em um CSV

Se você não armazenar e analisar os dados que extrai, eles serão inúteis. Nesta seção, você criará um programa avançado que recebe a entrada do usuário para o número de páginas de laptops a serem extraídas, extrai os títulos e os armazena em um arquivo CSV na pasta do seu projeto.

Para este programa, você precisa de uma biblioteca CSV pré-instalada, que pode ser importada usando o seguinte comando:

import csv

Após instalar a biblioteca CSV, você precisa descobrir como visitar um número variável de páginas dependendo da entrada do usuário.

Se você observar a estrutura de URL do site, notará que cada página de laptops é indicada usando um parâmetro de URL. Por exemplo, a URL da segunda página no diretório de laptops é https://webscraper.io/test-sites/e-commerce/static/computers/laptops?page=2.

Você pode visitar diferentes páginas alterando o parâmetro de URL ?page=2 com diferentes valores numéricos. Isso significa que você precisa solicitar ao usuário que insira o número de páginas a serem extraídas com o seguinte comando:

pages = int(input("enter the number of pages to scrape: "))

Para visitar cada página de 1 até o número de páginas inserido pelo usuário, você usa um loop for desta forma:

for i in range(1, pages+1):

Dentro desta função range, você usa 1 e pages+1 como argumentos para representar os valores em que o loop começa e termina. O segundo argumento da função é excluído do loop. Por exemplo, se a função range for range(1,5), o programa percorreria apenas de 1 a 4.

Em seguida, você precisa visitar cada página inserindo o valor i como parâmetro de URL na iteração. Você pode adicionar variáveis a uma string usando f-strings do Python.

Ao gerar uma string, você adiciona o prefixo f antes das aspas para indicar que é uma f-string. Dentro das aspas, você pode usar chaves para indicar variáveis.

Aqui está um exemplo de como você pode usar f-strings para imprimir variáveis junto com strings:

print(f"The value of the variable is {variable_name_goes_here}")

Voltando ao scraper, você pode utilizar f-strings escrevendo este bloco de código no arquivo:

     try:
             page.goto(f"https://webscraper.io/test-sites/e-commerce/static/computers/laptops?page={i}")

     except:
            print("Error")

Aguarde o carregamento da página com uma função de timeout e extraia os títulos usando o seguinte:

            page.wait_for_timeout(7000)

            titles = page.get_by_role("heading").all()

Depois de ter todos os elementos de título, você precisa abrir seu arquivo CSV, percorrer cada título, extrair o texto necessário e gravá-lo no arquivo.

Para abrir um arquivo CSV, use a seguinte sintaxe:

with open("laptops.csv", "a") as csvfile:

Aqui, você está abrindo o arquivo laptops.csv no modo de anexação (a). Você usa o modo de anexação aqui porque não quer perder dados antigos toda vez que o arquivo é aberto. Se o arquivo não existir, a biblioteca cria um na pasta do projeto. O CSV oferece vários modos para abrir um arquivo, incluindo os seguintes:

  • r é a opção padrão usada se nada for especificado. Abre o arquivo somente para leitura.
  • w abre um arquivo somente para escrita. Toda vez que um arquivo é aberto, os dados anteriores são sobrescritos.
  • a abre um arquivo para anexar dados. Os dados anteriores não são sobrescritos.
  • r+ abre um arquivo para leitura e escrita.
  • x cria um novo arquivo.

Abaixo do código anterior, você precisa declarar um objeto writer que permite manipular o arquivo CSV:

writer = csv.writer(csvfile)

Em seguida, percorra cada elemento de título e extraia o texto com o seguinte:

                for title in titles:
                    laptop = title.locator("a.title").all_inner_texts()

Isso fornece vários arrays, cada um contendo o título de laptops individuais. Para rejeitar arrays vazios, escreva o seguinte código condicional para o arquivo CSV:

               if len(laptop) == 1:
                        writer.writerow([laptop[0]])

A função writerow permite escrever novas linhas em um arquivo CSV.

Aqui está o código completo do programa:

from playwright.sync_api import sync_playwright
import csv

def main():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        pages = int(input("enter the number of pages to scrape: "))

        for i in range(1, pages+1):
            try:
                page.goto(f"https://webscraper.io/test-sites/e-commerce/static/computers/laptops?page={i}")

            except:
                print("Error")

            page.wait_for_timeout(7000)

            titles = page.get_by_role("heading").all()

            with open("laptops.csv", "a") as csvfile:
                writer = csv.writer(csvfile)
                for title in titles:
                    laptop = title.locator("a.title").all_inner_texts()
                    if len(laptop) == 1:
                        writer.writerow([laptop[0]])

        browser.close()             


main()

Após executar este código, seu arquivo CSV deve ter esta aparência:

Exemplo de como o arquivo CSV deve parecer

Conclusão

Neste artigo, você aprendeu como extrair, fazer parsing e armazenar HTML usando Python.

Embora este tutorial tenha sido relativamente simples, em um cenário do mundo real, você provavelmente enfrentaria vários obstáculos durante o scraping, incluindo CAPTCHAs, limites de taxa, mudanças no layout do site ou requisitos regulatórios. Felizmente, Bright Data pode ajudar. A Bright Data oferece ferramentas como proxies residenciais avançados para melhorar seu scraping, um Web Scraper IDE para construir scrapers em escala, e um Web Unlocker para desbloquear sites públicos, incluindo a resolução de CAPTCHAs. Essas ferramentas podem ajudá-lo a coletar dados precisos em escala e superar obstáculos. Além disso, o compromisso da Bright Data com o scraping ético garante que você permaneça dentro dos termos de serviço dos sites e das regulamentações legais.

Com a infraestrutura repleta de recursos da Bright Data, você pode se concentrar em extrair os dados valiosos de que precisa, deixando para trás as complexidades do scraping de dados. Comece seu teste grátis hoje!