Voltar ao blogue
A ciência da extração de dados da Web
Ștefan RăcilăLast updated on Mar 31, 20266 min read

Guia rápido de seletores CSS - Dicas e truques para extrair dados da Web

Guia rápido de seletores CSS - Dicas e truques para extrair dados da Web

Antes de criar um scraper web, é necessário compreender os dados que vai extrair e como aceder a esses dados. Existem várias formas de aceder aos dados de uma página web; a mais comum é utilizar seletores CSS. Outra alternativa é utilizar o XPath. Pode encontrar a ficha de referência do XPath aqui.

Introdução ao DOM

No processo de análise de um ficheiro HTML, o navegador cria uma representação dos dados na sua memória que se assemelha a uma árvore. Esta representação é chamada de DOM (Document Object Model). Para cada tag HTML, existe um nó emparelhado com ela no DOM. Um nó possui propriedades como nome, conteúdo, nós filhos, estilos, eventos, etc. Pode encontrar mais informações sobre como funciona a renderização do navegador neste artigo Como funciona a renderização do navegador — nos bastidores.

Quando dizemos que queremos aceder a dados de uma página web, o que pretendemos é percorrer o DOM até um conjunto específico de nós e extrair o conteúdo dentro deles. Neste artigo, vou dar-lhe várias dicas sobre como aceder rapidamente a esses nós utilizando seletores CSS.

O que são seletores CSS?

Porque é que são chamados de seletores CSS (Cascading Style Sheets)?

O CSS é utilizado para definir a aparência dos nós numa página. Com o CSS, pode escrever regras sobre como deve ser a aparência de um nó e como este deve interagir com outros nós. Uma regra é composta por um seletor e uma lista de estilos a substituir.

Portanto, estes seletores estão associados ao CSS porque esta é a sua utilização mais comum, mas não precisamos de os utilizar apenas com CSS. Com o CSS, pretende-se selecionar um nó e alterar a sua propriedade de estilo. Se pensarmos bem, queremos fazer a mesma coisa: selecionar um nó e fazer algo com ele, como ler o seu conteúdo ou acionar um evento. 

Como funcionam os seletores CSS?

Será de grande ajuda se visualizar a seleção a ocorrer. Digamos que pretende extrair todos os parágrafos de um site. Pretende obter todos os nós que tenham o nome `p`. Pode fazer isso manualmente. Basta percorrer todos os nós no DOM e selecionar apenas os nós que tenham node.tagName === 'P' (os nomes das tags estão em maiúsculas).

Aqui está um pequeno trecho de código que pode usar:

function scrapeByTagName(node, tagName) {
    if (node === null)
        return;
 
    node.childNodes.forEach(node => {
        //console.log(node.tagName)

        if (node.tagName?.toLowerCase() === tagName.toLowerCase()) {
            console.log(node)
            return
        }

        scrapeByTagName(node, tagName)
    });
}

Criei uma página web fictícia com este aspeto:

E aqui está o HTML correspondente:

<!DOCTYPE html>
<html lang="en">

<head>
    <link rel="stylesheet" href="styles.css">
    <script src="script.js"></script>
</head>

<body>
    <div id="wrapper">
        <h1 custom-attr="some data">Some Title</h1>
        <h2 custom-attr="some other data">Some Subtitle</h2>
        <div id="container">
            <p custom-attr>paragraph
                <span> subparagraph</span>
            </p>
            <p id="text">paragraph with id #text</p>
            <p class="bold">paragraph with class .bold</p>
            <p class="text">paragraph with class .text</p>
            <p class="text bold">paragraph with class .text.bold</p>
            <p class="text italic">paragraph with class .text.italic</p>
        </div>
    </div>
</body>

</html>

Depois de executar a função na consola do navegador, obtive esta resposta:

Como pode ver, a função registou todas as tags p.

Para ver a consola do navegador, tem de abrir o devTools e ir para o separador da consola ou premir a tecla Escape. Pode abrir o devTools clicando com o botão direito do rato num elemento e selecionando «Inspecionar» no menu ou utilizando o atalho de teclado Control + Shift + I.

Como usar seletores CSS?

Vamos usar dois métodos: querySelector e querySelectorAll. Estes métodos estão disponíveis em todos os objetos do tipo Element. Os nós que estamos a tentar extrair são do tipo HTMLElement, que herda do tipo Element.

O querySelector irá devolver o primeiro nó que corresponda ao seletor. O querySelectorAll irá devolver uma lista com todos os nós que correspondam ao seletor. Para replicar o exemplo mostrado anteriormente, basta chamar o querySelectorAll e percorrer a lista devolvida.

document.querySelectorAll('p').forEach(node => console.log(node))

Pode ver que utilizei document.querySelectorAll; isso deve-se ao facto de document estar definido no contexto da janela como a raiz da página web, ou seja, o equivalente à tag html. Pode utilizar os métodos querySelector com todos os nós, não apenas com o nó raiz.

Para realmente extrair algo, terá de utilizar uma biblioteca que consiga abrir uma janela do navegador e aceder a um URL. Só então o seu código será executado, no contexto dessa janela. Para saber mais sobre como fazer isto, recomendo este artigo: The Ultimate Guide to Web Scraping with JavaScript and Node.Js.

Aqui na WebScrapingAPI, usamos o Puppeteer. O Puppeteer é uma biblioteca que nos permite controlar instâncias de navegadores Chromium headless. Pode usar a nossa API para extrair dados de um site sem criar um scraper personalizado. Na verdade, temos um parâmetro chamado extract_rules que usa seletores CSS para extrair dados de uma determinada URL.

Folha de referência dos seletores CSS

O seletor *

Este seletor especifica todos os elementos da árvore. Não tem grande utilidade, mas é bom saber.

O seletor .class

Pode obter um nó com uma classe específica utilizando .class. É utilizado principalmente quando tem uma lista de itens. Como os itens de uma lista tendem a ter o mesmo aspeto, podem ter a mesma classe. Vamos procurar a classe .text.

Talvez queira selecionar o nó que tem a classe .bold.

Parece que há outro elemento que tem a classe .bold. Pode ser mais específico com o seletor de classe utilizando várias classes concatenadas.

Tenha em atenção que não há espaços entre as classes.

document.querySelectorAll('.text .bold').forEach(node => console.log(node))

Esta consulta não devolve nada do HTML acima, porque procura um elemento com a classe .text que tenha um elemento filho com a classe .bold (não necessariamente um elemento filho direto). A consulta devolveria o elemento filho, caso fosse encontrado. 

O seletor #id

E se um elemento não tiver uma classe ou se a classe for utilizada com demasiada frequência no documento? Pode utilizar o atributo ID para alcançar um nível mais profundo de especificidade. A desvantagem de utilizar o seletor id é que, na maioria dos casos, o id é único na página HTML, pelo que não é possível obter uma lista de nós com ele.

O seletor de nome de nó

Cada nó tem um nome. É o nome exato da tag correspondente no HTML. Pode obter todos os nós que tenham um nome específico utilizando o seu nome no seletor.

O seletor [atributo]

Pode deparar-se com situações em que deseja selecionar todos os nós que tenham um determinado atributo.

Também pode especificar o valor do atributo.

Ou até mesmo o que o valor do atributo deve conter. Pode usar o til ~ antes do sinal de igual para definir que o valor do atributo deve conter uma lista de palavras.

O seletor de atributos será o mais utilizado se decidires criar um scrapper. É muito poderoso e tem muito mais casos de utilização do que aqueles que mostrei aqui. Podes encontrar mais informações sobre como utilizar o seletor de atributos aqui: Seletores de Atributos W3.

Agrupamento de vários seletores

Obter todos os nós p que tenham um id.

Selecionar todos os nós span que são filhos de um nó p.

Obter todos os nós div que são filhos diretos do nó body.

Obter todos os nós p que tenham a classe .text

As opções de agrupamento destes seletores são infinitas. Tente copiar o código HTML acima e adicione mais nós. Depois, experimente diferentes combinações de seletores. Se quiser saber mais sobre seletores CSS em geral, a Mozilla disponibiliza um artigo fantástico que explica como os seletores CSS funcionam no desenvolvimento web.

Resumo

Se quiser aprender algo novo, aconselho-o a aprender primeiro como isso funciona. Sim, é um passo opcional, mas irá dar-lhe algumas informações que os outros não têm. 

No campo do desenvolvimento de software, esta informação irá ajudá-lo a procurar a resposta certa para o seu problema/erro. Poderá tomar o assunto nas suas próprias mãos e até criar uma solução personalizada.

Se queres realmente compreender os seletores CSS, precisas de compreender o DOM. É apenas uma árvore (um grafo acíclico não direcionado) com nós que têm um nome e alguns atributos. É isso mesmo. Quando escreves um seletor, estás apenas a escrever uma cadeia de caracteres que é analisada e utilizada para consultar o DOM.

Sobre o autor
Ștefan Răcilă, Desenvolvedor Full Stack @ WebScrapingAPI
Ștefan RăcilăDesenvolvedor Full Stack

Stefan Racila é engenheiro de DevOps e Full Stack na WebScrapingAPI, onde desenvolve funcionalidades do produto e mantém a infraestrutura que garante a fiabilidade da plataforma.

Comece a construir

Pronto para expandir a sua recolha de dados?

Junte-se a mais de 2.000 empresas que utilizam a WebScrapingAPI para extrair dados da Web à escala empresarial, sem quaisquer custos de infraestrutura.