Web Scraping com JavaScript: Extraia Dados da Web com node-fetch e cheerio!

A extração de dados da web é um dos temas mais fascinantes no universo da programação.

Mas, afinal, o que é *web scraping*?

E por que essa técnica se tornou tão relevante?

Vamos desvendar essas questões!

O que Significa Web Scraping?

O *web scraping* representa um processo automatizado, cujo objetivo é coletar dados específicos de páginas da internet.

As aplicações são vastas e diversificadas: desde a comparação de preços de produtos em diferentes lojas virtuais até a obtenção de cotações financeiras diárias, sem falar na criação de mecanismos de busca personalizados, análogos ao Google ou Yahoo. As possibilidades são praticamente infinitas.

Com o conhecimento adequado sobre a extração de dados de sites, você pode usar as informações coletadas para diversas finalidades.

O software responsável por essa extração é conhecido como *web scraper*. Neste artigo, você aprenderá a construir *web scrapers* utilizando JavaScript.

O *web scraping* pode ser dividido em duas etapas principais:

  • A coleta de dados por meio de requisições HTTP e navegadores *headless*.
  • A análise dos dados brutos para extrair exatamente as informações desejadas.

Sem mais delongas, vamos começar!

Preparando o Ambiente de Desenvolvimento

Assumindo que você já possui o Node.js instalado, podemos prosseguir. Caso contrário, consulte o guia de instalação do Node.js.

Para realizar o *web scraping* em JavaScript, utilizaremos os pacotes *node-fetch* e *cheerio*. A configuração do projeto será feita com o *npm* para facilitar o uso de pacotes de terceiros.

Vamos resumir as etapas necessárias para a configuração:

  • Crie uma pasta chamada `web_scraping` e acesse-a pelo terminal.
  • Execute o comando `npm init` para inicializar o projeto.
  • Responda às perguntas do *npm* de acordo com suas preferências.
  • Instale os pacotes com o comando:
npm install node-fetch cheerio

Agora, vamos entender o papel de cada pacote:

node-fetch

Este pacote introduz a funcionalidade `window.fetch` no ambiente Node.js, permitindo realizar requisições HTTP e obter os dados em formato bruto.

cheerio

O pacote cheerio é usado para interpretar e extrair as informações relevantes dos dados brutos recebidos.

Com *node-fetch* e *cheerio*, você terá as ferramentas essenciais para o *web scraping* com JavaScript. Não vamos nos aprofundar em todos os métodos oferecidos por esses pacotes; focaremos no fluxo geral do *web scraping* e nos métodos mais úteis para essa finalidade.

O aprendizado será prático, então vamos ao trabalho!

Extraindo os Vencedores da Copa do Mundo de Críquete

Nesta seção, vamos colocar a mão na massa e realizar o *web scraping* propriamente dito.

O que vamos extrair?

Pelo título da seção, você provavelmente já imaginou. Isso mesmo, vamos coletar todos os campeões e vice-campeões da Copa do Mundo de Críquete até o momento.

  • Crie um arquivo chamado `extract_cricket_world_cups_list.js` no seu projeto.
  • Usaremos a página da Wikipedia sobre a Copa do Mundo de Críquete como fonte de dados.
  • Inicialmente, vamos obter os dados brutos com o pacote *node-fetch*.
  • O código abaixo se encarrega de buscar os dados brutos da página da Wikipedia:
const fetch = require("node-fetch");

// Função para obter os dados brutos
const getRawData = (URL) => {
   return fetch(URL)
      .then((response) => response.text())
      .then((data) => {
         return data;
      });
};

// URL dos dados
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";

// Início do programa
const getCricketWorldCupsList = async () => {
   const cricketWorldCupRawData = await getRawData(URL);
   console.log(cricketWorldCupRawData);
};

// Execução da função principal
getCricketWorldCupsList();

Com isso, já temos os dados brutos da URL. Agora, vamos extrair as informações que precisamos. Para isso, usaremos o pacote *cheerio*.

A extração de dados de tags HTML com *cheerio* é bastante simples. Antes de lidarmos com os dados reais, vamos analisar alguns exemplos de como usar o *cheerio* para analisar dados HTML.

  • A análise de dados HTML é feita com o método `cheerio.load`.
const parsedSampleData = cheerio.load(
      `<div id="container"><p id="title">I'm title</p></div>`
   );
  • Analisamos o HTML acima. Como extrair o conteúdo da tag `

    `? É bem parecido com os seletores do DOM em JavaScript.

console.log(parsedSampleData(“#title”).text());

Você pode selecionar as tags que quiser. Para mais informações, você pode consultar o site oficial do cheerio.

  • Agora é o momento de extrair a lista da copa do mundo. Para isso, precisamos identificar as tags HTML que contêm as informações na página da Wikipedia. Inspeção a página da copa do mundo de críquete para obter essas informações.

Abaixo, está o código completo:

const fetch = require("node-fetch");
const cheerio = require("cheerio");

// Função para obter os dados brutos
const getRawData = (URL) => {
   return fetch(URL)
      .then((response) => response.text())
      .then((data) => {
         return data;
      });
};

// URL dos dados
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";

// Início do programa
const getCricketWorldCupsList = async () => {
   const cricketWorldCupRawData = await getRawData(URL);

   // Análise dos dados
   const parsedCricketWorldCupData = cheerio.load(cricketWorldCupRawData);

   // Extraindo os dados da tabela
   const worldCupsDataTable = parsedCricketWorldCupData("table.wikitable")[0]
      .children[1].children;

   console.log("Year --- Winner --- Runner");
   worldCupsDataTable.forEach((row) => {
      // Extraindo as tags `td`
      if (row.name === "tr") {
         let year = null,
            winner = null,
            runner = null;

         const columns = row.children.filter((column) => column.name === "td");

         // Extraindo o ano
         const yearColumn = columns[0];
         if (yearColumn) {
            year = yearColumn.children[0];
            if (year) {
               year = year.children[0].data;
            }
         }

         // Extraindo o vencedor
         const winnerColumn = columns[3];
         if (winnerColumn) {
            winner = winnerColumn.children[1];
            if (winner) {
               winner = winner.children[0].data;
            }
         }

         // Extraindo o vice-campeão
         const runnerColumn = columns[5];
         if (runnerColumn) {
            runner = runnerColumn.children[1];
            if (runner) {
               runner = runner.children[0].data;
            }
         }

         if (year && winner && runner) {
            console.log(`${year} --- ${winner} --- ${runner}`);
         }
      }
   });
};

// Execução da função principal
getCricketWorldCupsList();

E aqui estão os dados extraídos:

Year --- Winner --- Runner
1975 --- West Indies --- Australia
1979 --- West Indies --- England
1983 --- India --- West Indies
1987 --- Australia --- England
1992 --- Pakistan --- England
1996 --- Sri Lanka --- Australia
1999 --- Australia --- Pakistan
2003 --- Australia --- India
2007 --- Australia --- Sri Lanka
2011 --- India --- Sri Lanka
2015 --- Australia --- New Zealand
2019 --- England --- New Zealand

Interessante, não é?

Modelo de Web Scraping

A obtenção de dados brutos de uma URL é uma etapa comum em todos os projetos de *web scraping*. O que muda é a forma de extrair os dados de acordo com o que você precisa. Use o código abaixo como um modelo:

const fetch = require("node-fetch");
const cheerio = require("cheerio");
const fs = require("fs");
// Função para obter os dados brutos
const getRawData = (URL) => {
   return fetch(URL)
      .then((response) => response.text())
      .then((data) => {
         return data;
      });
};
// URL dos dados
const URL = "https://example.com/";
// Início do programa
const scrapeData = async () => {
   const rawData = await getRawData(URL);
   // Análise dos dados
   const parsedData = cheerio.load(rawData);
   console.log(parsedData);
   // Escreva o código para extrair os dados
   // aqui
   // ...
   // ...
};
// Execução da função principal
scrapeData();

Conclusão

Agora você já sabe como extrair dados de uma página da web. Chegou a sua vez de praticar. Experimente aplicar o que aprendeu e explore diferentes páginas.

Sugiro também que pesquise sobre *frameworks* populares de *web scraping* e soluções baseadas em nuvem para essa atividade.

Boas práticas de programação!

Gostou do artigo? Compartilhe com seus amigos!