O guia definitivo para raspagem da Web com C++
Raluca Penciuc em Jul 05 2021
Há dois milhões de anos, um grupo de homens das cavernas descobriu que uma pedra num pau podia ser útil. A partir daí, as coisas ficaram um pouco fora de controlo. Agora, os nossos problemas têm menos a ver com fugir de tigres dentes-de-sabre e mais com o facto de os colegas de equipa darem o nome de "did sutff" aos seus compromissos.
Embora as dificuldades tenham mudado, a nossa obsessão em criar ferramentas para as ultrapassar não mudou. Os raspadores da Web são uma prova disso mesmo. São ferramentas digitais concebidas para resolver problemas digitais.
Hoje vamos construir uma nova ferramenta a partir do zero, mas em vez de pedras e paus, vamos usar C++, que é indiscutivelmente mais difícil. Portanto, fique atento para saber como criar um raspador da Web em C++ e como usá-lo!
Compreender a raspagem da Web
Independentemente da linguagem de programação escolhida, é necessário compreender o funcionamento dos Web scrapers. Este conhecimento é fundamental para escrever o guião e ter uma ferramenta funcional no final do dia.
As vantagens da recolha de dados da Web
Não é difícil imaginar que um robot que faz toda a pesquisa por si é muito melhor do que copiar informações à mão. As vantagens aumentam exponencialmente se precisar de grandes quantidades de dados. Se estiver a treinar um algoritmo de aprendizagem automática, por exemplo, um web scraper pode poupar-lhe meses de trabalho.

Por uma questão de clareza, vamos analisar todas as formas em que os scrapers da Web o ajudam:
- Gastar menos tempo em trabalho aborrecido - esta é a vantagem mais aparente. Os scrapers extraem dados tão rapidamente quanto o seu browser demoraria a carregar a página. Dê ao bot uma lista de URLs e obtém instantaneamente o seu conteúdo.
- Obter maior precisão dos dados - as mãos humanas conduzem inevitavelmente a erros humanos. Em comparação, o bot extrairá sempre toda a informação, exatamente como é apresentada, e analisá-la-á de acordo com as suas instruções.
- Manter uma base de dados organizada - à medida que recolhe dados, pode tornar-se cada vez mais difícil manter o controlo de tudo. O scraper não só obtém conteúdos, como também os armazena no formato que lhe facilitar a vida.
- Utilizar informações actualizadas - em muitas situações, os dados mudam de um dia para o outro. Por exemplo, basta olhar para as bolsas de valores ou para as listas de lojas em linha. Com algumas linhas de código, o seu bot pode recolher as mesmas páginas em intervalos fixos e atualizar a sua base de dados com as informações mais recentes.
A WebScrapingAPI existe para lhe trazer todos esses benefícios e, ao mesmo tempo, contornar todos os diferentes bloqueios que os scrapers encontram frequentemente na Web. Tudo isto parece ótimo, mas como é que se traduz em projectos reais?
Casos de utilização de raspagem da Web
Existem muitas formas diferentes de utilizar os scrapers da Web. O céu é o limite! No entanto, alguns casos de utilização são mais comuns do que outros.

Vejamos mais pormenores sobre cada situação:
- Otimização para os motores de busca - A análise das páginas de resultados de pesquisa para as suas palavras-chave é uma forma fácil e rápida de determinar quem precisa de ultrapassar na classificação e que tipo de conteúdo o pode ajudar a fazê-lo.
- Pesquisa de mercado - Depois de verificar o desempenho dos seus concorrentes nas pesquisas, pode ir mais longe e analisar toda a sua presença digital. Utilize o web scraper para ver como utilizam o PPC, descrever os seus produtos, que tipo de modelo de preços utilizam, etc. Basicamente, qualquer informação pública está na ponta dos seus dedos.
- Proteção da marca - As pessoas estão a falar da sua marca. O ideal é que sejam coisas boas, mas isso não é uma garantia. Um bot está bem equipado para navegar em sites de avaliação e plataformas de redes sociais e informá-lo sempre que a sua marca for mencionada. Seja o que for que estejam a dizer, estará pronto para representar os interesses da sua marca.
- Geração de leads - Fazer a ponte entre a sua equipa de vendas e possíveis clientes na Internet raramente é fácil. Bem, torna-se muito mais fácil quando se utiliza um bot de raspagem da Web para recolher informações de contacto em registos de empresas online, como as Páginas Amarelas ou o Linkedin.
- Marketing de conteúdos - Criar conteúdos de alta qualidade dá muito trabalho, não há dúvida. Não só tem de encontrar fontes credíveis e uma grande quantidade de informação, como também aprender o tipo de tom e abordagem que o seu público vai gostar. Felizmente, estes passos tornam-se triviais se tiver um bot para fazer o trabalho pesado.
Há muitos outros exemplos por aí. É claro que também pode desenvolver uma forma totalmente nova de utilizar a extração de dados em seu benefício. Encorajamos sempre a utilização criativa da nossa API.
Os desafios da recolha de dados da Web
Por muito valiosos que sejam os web scrapers, nem tudo são raios de sol e arco-íris. Alguns sítios Web não gostam de ser visitados por bots. Não é difícil programar o seu raspador para evitar sobrecarregar seriamente o sítio Web visitado, mas a sua vigilância contra os bots justifica-se. Afinal, o sítio pode não ser capaz de distinguir entre um bot bem-educado e um malicioso.
Por conseguinte, há alguns desafios que os raspadores enfrentam quando andam por aí.

Os obstáculos mais problemáticos são:
- Bloqueios de IP - Existem várias formas de determinar se um visitante é um humano ou uma máquina. O curso de ação depois de identificar um bot, no entanto, é muito mais simples - bloqueio de IP. Embora isto não aconteça muitas vezes se tomar as precauções necessárias, é uma boa ideia ter um grupo de proxy preparado para que possa continuar a extrair dados mesmo que um IP seja banido.
- Impressão digital do navegador - Cada pedido que envia a um sítio Web também fornece algumas das suas informações. O IP é o exemplo mais comum, mas os cabeçalhos dos pedidos também informam o site sobre o seu sistema operativo, browser e outros pequenos detalhes. Se um sítio Web utilizar estas informações para identificar quem está a enviar os pedidos e se aperceber de que está a navegar muito mais depressa do que um ser humano deveria, pode esperar ser imediatamente bloqueado.
- Renderização de Javascript - A maioria dos sítios Web modernos é dinâmica. Ou seja, utilizam código javascript para personalizar as páginas para o utilizador e oferecer uma experiência mais personalizada. O problema é que os bots simples ficam presos nesse código, uma vez que não o conseguem executar. O resultado: o raspador recupera javascript em vez do HTML pretendido que contém informações relevantes.
- Captchas - Quando os sítios Web não têm a certeza se um visitante é um humano ou um bot, redireccionam-no para uma página Captcha. Para nós, é um ligeiro aborrecimento, na melhor das hipóteses, mas para os bots, é normalmente uma paragem completa; a menos que tenham scripts de resolução de Captcha incluídos.
- Limitação de pedidos - A forma mais simples de evitar que os visitantes sobrecarreguem o servidor do sítio Web consiste em limitar o número de pedidos que um único IP pode enviar num determinado período de tempo. Quando esse número é atingido, o scraper pode ter de esperar pelo temporizador ou pode ter de resolver um Captcha. De qualquer forma, não é bom para o seu projeto de extração de dados.
Compreender a Web
Para construir um web scraper, é preciso conhecer alguns conceitos-chave de como a Internet funciona. Afinal, o seu bot não só vai usar a Internet para recolher dados, como também tem de se misturar com os outros milhares de milhões de utilizadores.
Gostamos de pensar que os sítios Web são como livros e que ler uma página significa apenas folhear o número correto e olhar. Na realidade, é mais parecido com telegramas enviados entre si e o livro. Pedimos uma página e ela é-nos enviada. Depois, pede-se a página seguinte e acontece a mesma coisa.
Todas estas idas e vindas acontecem através do HTTP, ou Protocolo de Transferência de Hipertexto. Para o utilizador, o visitante, ver uma página, o seu browser envia um pedido HTTP e recebe uma resposta HTTP do servidor. O conteúdo que pretende será incluído nessa resposta.
Os pedidos HTTP são constituídos por quatro componentes:
- O URL (Uniform Resource Locator) é o endereço para o qual está a enviar pedidos. Conduz a um recurso único que pode ser uma página Web inteira, um único ficheiro ou qualquer outra coisa.
- O método indica o tipo de ação que se pretende realizar. O método mais comum é o GET, que recupera dados do servidor. Aqui está uma lista dos métodos mais comuns.
- Os cabeçal hos são pedaços de metadados que dão forma ao seu pedido. Por exemplo, se tiver de fornecer uma palavra-passe ou credenciais para aceder aos dados, estas são colocadas num cabeçalho especial. Se pretender receber dados especificamente em formato JSON, deve mencioná-lo num cabeçalho. O User-Agent é um dos cabeçalhos mais conhecidos na recolha de dados da Web, porque os sítios Web o utilizam para identificar os visitantes.
- O Corpo é a parte de uso geral do pedido que armazena dados. Se estiver a receber conteúdo, provavelmente estará vazio. Por outro lado, quando quiser enviar informações para o servidor, elas serão encontradas aqui.
Depois de enviar o pedido, obterá uma resposta, mesmo que o pedido não tenha recebido quaisquer dados. A estrutura tem o seguinte aspeto:
- O código de estado é um código de três dígitos que indica rapidamente o que aconteceu. Resumidamente, um código que começa por "2" significa normalmente um êxito e um código que começa por "4" indica uma falha.
- Os cabeçalhos têm a mesma função que os seus homólogos. Por exemplo, se receber um tipo específico de ficheiro, um cabeçalho indica-lhe o formato.
- O corpo também está presente. Se pediu conteúdo com GET e este foi bem sucedido, encontrará os dados aqui.
As APIs REST usam protocolos HTTP, assim como os navegadores da Web. Assim, se decidir que os raspadores Web C++ dão muito trabalho, esta informação também será útil se optar por utilizar WebScrapingAPI, que já trata de todos os desafios de extração de dados.
Compreender o C++
Em termos de linguagens de programação, não há nada mais antiquado do que C e C++. A linguagem surgiu em 1985 como a versão aperfeiçoada do "C com classes".
Embora o C++ seja utilizado para programação de uso geral, não é realmente a primeira linguagem que se consideraria para um web scraper. Tem algumas desvantagens, mas a ideia tem os seus méritos. Vamos explorá-los, sim?
O C++ é orientado para objectos, o que significa que utiliza classes, abstração de dados e herança para tornar o seu código mais fácil de reutilizar e redirecionar para diferentes necessidades. Uma vez que os dados são tratados como um objeto, é mais fácil armazená-los e analisá-los.
Muitos programadores sabem pelo menos um pouco de C++. Mesmo que não o tenha aprendido na universidade, é provável que você (ou um colega de equipa) saiba um pouco de C++. Isso estende-se a toda a comunidade de desenvolvimento de software, pelo que não será difícil obter uma segunda opinião sobre o código.
O C++ é altamente escalável. Se começar com um pequeno projeto e decidir que a recolha de dados na Web é para si, a maior parte do código é reutilizável. Com alguns ajustes aqui e ali, estará pronto para volumes de dados muito maiores.
Por outro lado, o C++ é uma linguagem de programação estática. Embora assegure uma melhor integridade dos dados, não é tão útil como as linguagens dinâmicas quando se lida com a Internet.
Para além disso, o C++ não é adequado para a construção de crawlers. Isso pode não ser um problema se você quiser apenas um scraper. Mas se pretender adicionar um crawler para gerar listas de URL, o C++ não é uma boa escolha.
Muito bem, falámos de muitas coisas importantes, mas vamos ao cerne do artigo - codificar um web scraper em C++.
Construir um raspador da Web com C++
Pré-requisitos
- IDE C++. Neste guia, utilizaremos o Visual Studio.
- O vcpkg é um gestor de pacotes C/C++ criado e suportado pelo Windows
- cpr é uma biblioteca C/C++ para pedidos HTTP, construída como um wrapper para o clássico cURL e inspirada na biblioteca de pedidos Python.
- O gumbo é um analisador de HTML inteiramente escrito em C, que fornece wrappers para várias linguagens de programação, incluindo C++.
Configurar o ambiente
1. Depois de descarregar e instalar o Visual Studio, crie um projeto simples utilizando um modelo de aplicação de consola.

2. Agora vamos configurar nosso gerenciador de pacotes. O Vcpkg fornece um tutorial bem escrito para o ajudar a começar o mais rápido possível.
Nota: quando a instalação estiver concluída, seria útil definir uma variável de ambiente para que possa executar o vcpkg a partir de qualquer local no seu computador.
3. Agora é altura de instalar as bibliotecas de que necessitamos. Se definiu uma variável de ambiente, então abra qualquer terminal e execute os seguintes comandos:
> vcpkg install cpr
> vcpkg install gumbo
> vcpkg integrate install
Se não definiu uma variável de ambiente, simplesmente navegue até a pasta onde instalou o vcpkg, abra uma janela de terminal e execute os mesmos comandos.
Os dois primeiros comandos instalam os pacotes de que precisamos para construir o nosso raspador e o terceiro ajuda-nos a integrar as bibliotecas no nosso projeto sem esforço.
Escolha um site e inspeccione o HTML
E agora está tudo pronto! Antes de construir o Web scraper, temos de escolher um sítio Web e inspecionar o seu código HTML.
Fomos à Wikipédia e escolhemos uma página ao acaso da secção "Sabia que...". Assim, a página raspada de hoje será o artigo da Wikipédia sobre a defesa da semente de papoila, e vamos extrair alguns dos seus componentes. Mas primeiro, vamos dar uma olhada na estrutura da página. Clique com o botão direito do rato em qualquer parte do artigo, depois em "Inspecionar elemento" e voilá! O HTML é nosso.

Extrair o título
Agora podemos começar a escrever o código. Para extrair a informação, temos de descarregar o HTML localmente. Primeiro, importe as bibliotecas que acabámos de descarregar:
#include <iostream>
#include <fstream>
#include "cpr/cpr.h"
#include "gumbo.h"
Em seguida, fazemos um pedido HTTP ao sítio Web de destino para obter o HTML.
std::string extract_html_page()
{
cpr::Url url = cpr::Url{"https://en.wikipedia.org/wiki/Poppy_seed_defence"};
cpr::Response response = cpr::Get(url);
return response.text;
}
int main()
{
std::string page_content = extract_html_page();
}
A variável page_content contém agora o HTML do artigo e vamos utilizá-la para extrair os dados de que precisamos. É aqui que a biblioteca gumbo se torna útil.
Utilizamos o método gumbo_parse para converter a string page_content anterior numa árvore HTML e, em seguida, chamamos a nossa função implementada search_for_title para o nó raiz.
int main()
{
std::string page_content = extract_html_page();
GumboOutput* parsed_response = gumbo_parse(page_content.c_str());
search_for_title(parsed_response->root);
// free the allocated memory
gumbo_destroy_output(&kGumboDefaultOptions, parsed_response);
}
The called function will traverse the HTML tree in-depth to look for the <h1> tag by making recursive calls. When it finds the title, it’s displaying it in the console and will exit the execution.
void search_for_title(GumboNode* node)
{
if (node->type != GUMBO_NODE_ELEMENT)
return;
if (node->v.element.tag == GUMBO_TAG_H1)
{
GumboNode* title_text = static_cast<GumboNode*>(node->v.element.children.data[0]);
std::cout << title_text->v.text.text << "\n";
return;
}
GumboVector* children = &node->v.element.children;
for (unsigned int i = 0; i < children->length; i++)
search_for_title(static_cast<GumboNode*>(children->data[i]));
}
Extrair as ligações
O mesmo princípio principal é aplicado ao resto das etiquetas, percorrendo a árvore e obtendo aquilo em que estamos interessados. Vamos pegar em todos os links e extrair o seu atributo href.
void search_for_links(GumboNode* node)
{
if (node->type != GUMBO_NODE_ELEMENT)
return;
if (node->v.element.tag == GUMBO_TAG_A)
{
GumboAttribute* href = gumbo_get_attribute(&node->v.element.attributes, "href");
if (href)
std::cout << href->value << "\n";
}
GumboVector* children = &node->v.element.children;
for (unsigned int i = 0; i < children->length; i++)
{
search_for_links(static_cast<GumboNode*>(children->data[i]));
}
}
Está a ver? Praticamente o mesmo código, exceto a etiqueta que estamos à procura. O método gumbo_get_attribute pode extrair qualquer atributo que nomearmos. Portanto, pode usá-lo para procurar classes, IDs, etc.
É essencial verificar o valor nulo do atributo antes de o apresentar. Em linguagens de programação de alto nível, isto é desnecessário, uma vez que será simplesmente apresentada uma cadeia de caracteres vazia, mas em C++, o programa irá falhar.
Escrever num ficheiro CSV
Há muitas hiperligações por aí, todas misturadas no conteúdo. E este artigo também é muito curto. Por isso, vamos guardá-las todas externamente e ver como podemos fazer uma distinção entre elas.
Primeiro, criamos e abrimos um ficheiro CSV. Fazemo-lo fora da função, mesmo junto às importações. A nossa função é recursiva, o que significa que teremos MUITOS ficheiros se criar um novo ficheiro de cada vez que for chamada.
std::ofstream writeCsv("links.csv");
Depois, na nossa função principal, escrevemos a primeira linha do ficheiro CSV mesmo antes de chamar a função pela primeira vez. Não se esqueça de fechar o ficheiro depois de concluída a execução.
writeCsv << "type,link" << "\n";
search_for_links(parsed_response->root);
writeCsv.close();
Now, we write its content. In our search_for_links function, when we find a <a> tag, instead of displaying in the console now we do this:
if (node->v.element.tag == GUMBO_TAG_A)
{
GumboAttribute* href = gumbo_get_attribute(&node->v.element.attributes, "href");
if (href)
{
std::string link = href->value;
if (link.rfind("/wiki") == 0)
writeCsv << "article," << link << "\n";
else if (link.rfind("#cite") == 0)
writeCsv << "cite," << link << "\n";
else
writeCsv << "other," << link << "\n";
}
}
Pegamos no valor do atributo href com este código e colocamo-lo em 3 categorias: artigos, citações e o resto.

É claro que pode ir muito mais longe e definir os seus próprios tipos de ligação, como os que parecem um artigo mas que, na realidade, são um ficheiro, por exemplo.
Alternativas de raspagem da Web
Agora já sabe como construir o seu próprio "web scraper" com C++. Porreiro, não é?
Ainda assim, pode ter dito a si próprio a dada altura "Isto está a começar a dar mais trabalho do que vale a pena!", e nós compreendemos perfeitamente. Verdade seja dita, codificar um raspador é uma excelente experiência de aprendizagem, e os programas são adequados para pequenos conjuntos de dados, mas é só isso.
Uma API de raspagem da Web é a sua melhor opção se precisar de uma ferramenta de extração de dados rápida, fiável e escalável. Isto porque inclui todas as funcionalidades de que necessita, como um conjunto de proxy rotativo, renderização Javascript, solucionadores Captcha, opções de geolocalização e muito mais.
Não acredita em mim? Então, tem de ver com os seus próprios olhos! Inicie a sua avaliação gratuita da WebScrapingAPI e descubra como a recolha de dados da Web pode ser acessível!
Notícias e actualizações
Mantenha-se atualizado com os mais recentes guias e notícias sobre raspagem da Web, subscrevendo a nossa newsletter.
We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Artigos relacionados

Saiba qual é o melhor browser para contornar os sistemas de deteção Cloudflare enquanto faz web scraping com o Selenium.


Descubra como extrair e organizar eficientemente dados para raspagem da Web e análise de dados através de análise de dados, bibliotecas de análise de HTML e metadados schema.org.


Os selectores XPath são melhores do que os selectores CSS para a recolha de dados da Web? Conheça os pontos fortes e as limitações de cada método e faça a escolha certa para o seu projeto!
