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!