Compreender a raspagem da Web
A enorme quantidade de dados da Internet está lamentavelmente dispersa por milhares de milhões de sites. Por isso, os programadores precisam de uma forma de recolher e processar esses dados, para poderem oferecer aos utilizadores novos produtos inovadores. No entanto, a recolha manual de informações não é, de forma alguma, uma boa ideia, uma vez que o volume é frequentemente demasiado grande e os dados estão em constante mudança.
A solução consiste em extrair os dados automaticamente. Em suma, é isso que o web scraping faz.
Por que deve extrair dados
Quanto mais informação, mais ideias, oportunidades e benefícios. Depois de processada, essa informação pode revelar-se inestimável para si ou para os seus clientes. Aqui estão apenas algumas formas como o web scraping pode ser utilizado:
- Ferramentas de comparação de preços - Recolha de dados de vários sites para obter uma visão geral dos preços de um determinado tipo de produto.
- Estudo de mercado - Descobrir quem são os seus principais concorrentes e o que estão a fazer.
- Aprendizagem Automática - Recolha de conjuntos de dados de treino e de teste para um modelo de aprendizagem automática.
- Qualquer ideia que exija o acesso a uma quantidade considerável de dados.
Por exemplo, um possível caso de utilização é a criação de uma aplicação nutricional que permita aos utilizadores registar as suas refeições. Idealmente, os utilizadores bastariam abrir a aplicação, procurar os produtos que consumiram, adicioná-los à aplicação e controlar quantas calorias ainda podem consumir depois.
No entanto, a ferramenta deve fornecer uma lista exaustiva de todos os produtos possíveis e dos seus valores nutricionais. Esta lista pode ser criada e atualizada automaticamente através da recolha de informações nutricionais de vários sites.
Os desafios da extração de dados da Web
Embora a extração de dados da Web seja muito útil para quem utiliza o bot, por vezes os sites não gostam de partilhar o seu conteúdo e podem tentar impedi-lo. Algumas das formas que podem adotar para o fazer são:
- Códigos Captcha - Qualquer página pode utilizar Captchas, mesmo que estes não sejam visíveis. Quando se efetuam várias solicitações, pode aparecer um código Captcha e interromper o funcionamento do seu web scraper.
- Bloqueio de IP - Alguns sites optam por bloquear o seu IP assim que detetam um tráfego excessivo proveniente do seu lado.
- Bloqueio geográfico - Alguns conteúdos podem estar disponíveis apenas em determinados países, ou poderá receber dados específicos de uma região quando procura informações sobre outra.
- JavaScript - A maioria dos sites atuais utiliza JavaScript de uma forma ou de outra. Alguns podem apresentar o seu conteúdo de forma dinâmica, o que complica as coisas, uma vez que o código-fonte da página não é idêntico ao conteúdo da página tal como é apresentado.
Superar estes desafios pode exigir muito trabalho, mas existem alternativas. Para o ajudar, criámos a WebscrapingAPI, que resolve todos estes problemas, permitindo-lhe desenvolver a sua solução mais rapidamente e com menos complicações.
Compreender a Web
Sempre que um utilizador da Internet acede a um site, o navegador cria um pedido HTTP (Hypertext Transfer Protocol). Pode considerar um pedido como uma mensagem do cliente (o computador do utilizador) para o servidor (o computador onde o site está alojado), na qual o cliente especifica o que pretende receber.
Por cada pedido enviado, receberá uma resposta. A resposta pode ser bem-sucedida ou indicar um erro, como o famoso código de erro «404 - Página não encontrada». O conteúdo de um site encontra-se normalmente no corpo da resposta recebida do servidor.

Tanto os pedidos como as respostas contêm um cabeçalho e um corpo, utilizados para trocar informações. Além disso, os pedidos podem utilizar vários métodos, sendo o mais comum o GET (utilizado ao aceder a uma página web). Estes métodos indicam a ação que o cliente pretende realizar.
Por exemplo, ao registar-se ou atualizar a sua palavra-passe num site, pretende que os seus dados fiquem ocultos no navegador, e os sites podem utilizar os métodos POST ou PUT para este tipo de pedido.
O cabeçalho de uma solicitação contém várias propriedades. Vamos analisar as mais importantes:
- Host - O nome de domínio do servidor.
- User-Agent - Informações sobre o cliente que efetuou o pedido, tais como o navegador e o sistema operativo.
- Cookie - Um conjunto de propriedades associadas ao cliente.
- Accept - Um parâmetro utilizado para receber a resposta do servidor num tipo específico, como text/plain ou application/json.
No entanto, os pedidos são exclusivos das páginas web. São feitos também para imagens, estilos e código JavaScript, separadamente da página. Pode ter uma visão geral de todos os pedidos que o seu navegador Google Chrome faz ao aceder a uma página web premindo F12 numa página, selecionando o separador «Rede» e atualizando a página em que se encontra. Deverá ver, no final, algo semelhante a isto:

Compreender o PHP
O PHP é uma das linguagens de programação web mais antigas e populares utilizadas para back-ends de aplicações. Existe desde 1995 e encontra-se atualmente na sua 8.ª versão.
Os programadores optam por esta linguagem de programação devido à sua sintaxe simples e à facilidade de execução, uma vez que tudo o que é necessário para executar código PHP é um computador com o PHP instalado. Além disso, dado que já existe há muito tempo, existem muitos recursos e apoio para resolver e depurar erros de PHP.
O PHP também conta com muitos frameworks e CMS (Sistemas de Gestão de Conteúdos) populares desenvolvidos nesta linguagem de programação. Exemplos famosos são o WordPress, o Drupal, o Magento e o Laravel.
No entanto, também existem algumas desvantagens. Por exemplo, é mais difícil extrair conteúdo dinâmico em comparação com o Python ou o JavaScript. Contudo, se precisar apenas de informações de páginas simples, o PHP é definitivamente uma boa solução e pode ajudá-lo a guardar ou armazenar os dados extraídos com muito mais facilidade.
O que vai precisar
Está tudo bem até agora? Pronto para criar o seu primeiro web scraper? Antes de começar, deve ter uma forma de executar o seu código PHP. Pode optar por um servidor Apache/Nginx com PHP instalado e executar o código diretamente no seu navegador, ou pode executar o código a partir da linha de comandos.
Vamos facilitar a nossa vida utilizando uma biblioteca para processar o conteúdo extraído. Algumas das bibliotecas de extração de dados mais populares em PHP são a Goutte, a Simple HTML DOM, a Panther e a htmlSQL. Em alternativa, pode optar por processar o conteúdo utilizando expressões regulares.
Neste guia, utilizaremos o Simple HTML DOM. No entanto, para pedidos mais avançados, utilizaremos também a biblioteca PHP chamada CURL.
Utilização do DOM HTML simples
O Simple HTML Dom é uma biblioteca desenvolvida para versões do PHP a partir da 5.6, que nos permite aceder ao conteúdo da página de uma forma muito mais fácil — através de seletores. Pode descarregar a biblioteca aqui e deve também ler a documentação.
Do ficheiro zip disponível no link de download, só vai precisar do ficheiro simple_html_dom.php, que deve colocar na mesma pasta onde irá escrever o código do scraper.
Para incluir a biblioteca no código, basta esta única linha de código:
include 'simple_html_dom.php'; // Se a biblioteca estiver noutra pasta, deve fazer o seguinte: include 'caminho_para_a_biblioteca/simple_html_dom.php'Instalar o PHP-CURL
Embora nem sempre seja necessário, terá de enviar cabeçalhos diferentes para pedidos mais avançados. A utilização da biblioteca PHP-CURL irá ajudar.
Para o instalar numa máquina Ubuntu, pode utilizar o seguinte comando:
sudo apt-get install php-curl
Depois de instalar a biblioteca, não se esqueça de reiniciar o servidor Apache/Nginx.
Criar o seu próprio raspador da Web
Agora que temos tudo o que precisamos, está na hora de extrair os dados! Primeiro, deve decidir qual o site e o conteúdo que pretende extrair. Para este artigo, iremos extrair o conteúdo da lista dos filmes mais bem classificados do IMDB.
1. Verifique o conteúdo do site
A maior parte do conteúdo da Web é apresentada utilizando HTML. Uma vez que precisamos de extrair conteúdo específico do código-fonte HTML, é também necessário compreendê-lo. Temos primeiro de analisar o aspecto do código-fonte da página para saber quais os elementos a extrair da mesma.
Pode fazer isto no Google Chrome clicando com o botão direito do rato no elemento que pretende extrair e, em seguida, selecionando «Inspecionar elemento». Isto deverá abrir uma janela no seu navegador com o código-fonte da página e os estilos aplicados aos elementos. Nesta janela, o único separador que precisamos de verificar é «Elementos», que nos mostrará como está estruturado o DOM HTML da página.

Por exemplo, a página contém uma tabela com as classes «chart» e «full-width», como se pode ver na imagem acima. Nesta tabela, cada célula tem a sua própria classe (posterColumn, titleColumn, etc.), que podemos utilizar para criar um seletor. Assim, podemos aceder apenas aos dados necessários.
Confuso? Não se preocupe, os passos a seguir vão esclarecer tudo.
2. Enviar um pedido a partir do PHP
Enviar um pedido, neste caso, significa basicamente aceder diretamente ao código HTML de uma página através de código PHP. Existem duas formas de o fazer.
Em primeiro lugar, podemos utilizar a biblioteca PHP-CURL, que também nos permite modificar os cabeçalhos e o corpo da mensagem que enviamos na nossa solicitação.
<?php
header("Content-Type: text/plain"); // We choose to display the content as plain text
$ch = curl_init("https://www.imdb.com/chart/top/");
curl_setopt($ch, CURLOPT_HEADER, 0);
$response = curl_exec($ch); // Running the request
if (curl_error($ch)) {
echo curl_error($ch); // Displaying possible errors from the request
} else {
echo $response; // Displaying the content of the response
}
curl_close($ch);
?>
Outra opção é uma linha única, utilizando o método file_get_contents($url) , mas isso pode ser insuficiente em alguns casos. Para enviar cabeçalhos nesta solicitação, é necessário utilizar um contexto criado com o método stream_context_create.
<?php
header("Content-Type: text/plain"); // We choose to display the content as plain text
echo file_get_contents('https://www.imdb.com/chart/top/'); // We retrieve and display the contents of the response in a single line
?>
Deve decidir qual o método a utilizar com base na complexidade do scraper que pretende criar.
Os dois trechos de código acima irão apresentar o código-fonte HTML da página que estamos a extrair, o mesmo que fica visível quando se inspeciona o site. Vamos usar a primeira linha do código para apresentar os resultados como texto simples. Caso contrário, serão apresentados diretamente como HTML.
Se houver alguma diferença na estrutura HTML, isso significa que existe um código JavaScript a ser executado no site e a alterar o conteúdo assim que um utilizador acede ao mesmo. Mais adiante neste artigo, apresentamos uma dica sobre como lidar com essa situação.
3. Extrair os dados
A partir da página selecionada, iremos extrair apenas o título dos filmes e a classificação associada a cada um deles. Como vimos anteriormente, o conteúdo é apresentado numa tabela em que cada célula tem a sua própria classe.
Com isto, podemos optar por extrair todas as linhas da tabela. Depois, analisamos cada linha individualmente para encontrar as células que nos interessam.
O seguinte trecho de código deve fazer exatamente isso:
<?php
header("Content-Type: text/plain"); // We choose to display the content as plain text
include 'simple_html_dom.php';
$html_dom = file_get_html('https://www.imdb.com/chart/top/'); // We retrieve the contents using file_get_html from simple_html_dom
$table_rows = $html_dom->find('table.chart tbody tr'); // Getting all of the table rows
foreach($table_rows as $table_row) {
$title_element = $table_row->find('.titleColumn a', 0);
$rating_element = $table_row->find('.ratingColumn strong', 0);
if (!is_null($title_element) && !is_null($rating_element)) { // Checking if the row has a title and a rating column
echo $title_element->innertext . ' has rating ' . $rating_element->innertext . PHP_EOL; // If it does then we print it
}
}
?>
Pode ver que utilizámos o seletor«table.chart tbody tr»para extrair todas as linhas da tabela. É aconselhável utilizar seletores tão específicos quanto possível, para que possa distinguir os elementos de que necessita dos restantes.
Depois de recuperar as linhas, percorremos todas elas, procurando elementos com a classe titleColumn ou ratingColumn. Se o código encontrasse algum, exibia a sua propriedade innerText.
É importante referir que , neste exemplo , utilizámos a função `file_get_html` em vez de `file_get_contents` . Isto deve-se ao facto de esta função pertencer à biblioteca `simple_html_dom ` e funcionar como um wrapper da função `file_get_contents`.
4. Exportar os dados
Nos exemplos acima, recolhemos os dados do site e apresentámo-los diretamente no ecrã. No entanto, também é possível guardar os dados em PHP com bastante facilidade.
Pode guardar os dados extraídos num ficheiro .txt, como JSON, como CSV ou até enviá-los diretamente para uma base de dados. O PHP é muito bom nisso. Basta armazená-los numa matriz e colocar o conteúdo da matriz num novo ficheiro.
<?php
include 'simple_html_dom.php';
$scraped_data = [];
$html_dom = file_get_html('https://www.imdb.com/chart/top/'); // We retrieve the contents using file_get_html from simple_html_dom
$table_rows = $html_dom->find('table.chart tbody tr'); // Getting all of the table rows
foreach($table_rows as $table_row) {
$title_element = $table_row->find('.titleColumn a', 0);
$rating_element = $table_row->find('.ratingColumn strong', 0);
if (!is_null($title_element) && !is_null($rating_element)) { // Checking if the row has a title and a rating column
$scraped_data[] = [
'title' => $title_element->innertext,
'rating' => $rating_element->innertext,
];
}
}
file_put_contents('file.json', json_encode($scraped_data)); // Saving the scraped data in a .json file
// Saving the scraped data as a csv
$csv_file = fopen('file.csv', 'w');
fputcsv($csv_file, array_keys($scraped_data[0]));
foreach ($scraped_data as $row) {
fputcsv($csv_file, array_values($row));
}
fclose($csv_file);
?>
O código acima utiliza o mesmo conteúdo que extraímos anteriormente e cria dois ficheiros, um CSV e um JSON, com todos os filmes mais bem classificados e as respetivas classificações.
Dicas e truques
1. Gestão de erros
Ao programar em PHP e extrair dados de sites que podem sofrer alterações a qualquer momento, é normal que surjam erros. Um bom trecho de código que pode utilizar para depuração são as três linhas seguintes, colocadas no início de qualquer script PHP:
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
Isto irá ajudá-lo a identificar problemas no seu código mais rapidamente e a atualizar o seu script quando necessário.
2. Definir cabeçalhos nas solicitações em PHP
Por vezes, ao efetuar um pedido, poderá ser necessário enviar também alguns cabeçalhos. Por exemplo, ao trabalhar com uma API, poderá ser necessário um token de autorização, ou poderá preferir que o conteúdo seja fornecido em formato JSON em vez de texto simples. É possível adicionar cabeçalhos tanto com o curl como com o file_get_contents. Veja aqui como fazê-lo com o curl:
$ch = curl_init("http://httpbin.org/ip");
curl_setopt($ch, CURLOPT_HEADER, [
'accept: application/json'
]);
$response = curl_exec($ch); // Executar o pedido
E quanto à função file_get_contents:
$opts = [
"http" => [
"method" => "GET",
"header" => "accept: application/json\r\n"
]
];
$context = stream_context_create($opts);
$result = file_get_contents("http://httpbin.org/ip", false, $context);3. Utilizar o curl ou o file_get_contents com o simple_html_dom
Quando extraímos conteúdo do IMDB, utilizámos a função `file_get_html` da biblioteca ` simple_html_dom ` para fazer o scraping. Esta abordagem funciona para pedidos simples, mas não necessariamente para os mais complexos. Se precisar de enviar cabeçalhos, é melhor utilizar um dos métodos apresentados na dica anterior.
Para as utilizar em vez de `file_get_html`, basta extrair o conteúdo e, em seguida, usar `str_get_html` para o converter num objeto DOM, desta forma:
$opts = [
"http" => [
"method" => "GET",
"header" => "accept: text/html\r\n"
]
];
$context = stream_context_create($opts);
$result = file_get_contents("https://www.imdb.com/chart/top/", false, $context);
$html_dom = str_get_html($result);
Além disso, tenha em conta que o simple_html_dom tem, por predefinição, alguns limites (que podem ser consultados no ficheiro simple_html_dom.php). Por exemplo, o conteúdo do site pode ter até 600 000 caracteres. Se pretender alterar este limite, basta defini-lo no início do seu código, antes de incluir a biblioteca simple_html_dom:
define('MAX_FILE_SIZE', 999999999);4. Extração de conteúdo dinâmico
Se estiver a extrair dados de um site dinâmico, terá de aceder ao mesmo tal como um navegador o faria. Caso contrário, não conseguirá extrair os dados reais e, em vez disso, obterá código JavaScript.
Terá de instalar um controlador de navegador, como o chromium-chromedriver ou o firefox-geckodriver. Extrair conteúdo dinâmico em PHP é um tema mais avançado, mas, se estiver interessado, pode tentar fazê-lo consultando a documentação da biblioteca panther.
Em alternativa, uma solução muito mais simples consiste em utilizar a WebScrapingAPI, que resolve a maioria dos problemas. A API contorna bloqueios de IP e Captchas através da nossa rede de proxies, ao mesmo tempo que executa javascript. O resultado: dispõe imediatamente de um scraper avançado, reduzindo o tempo de desenvolvimento e de espera.
Aqui está um exemplo de código que irá apresentar o conteúdo de https://httpbin.org/ip diretamente em PHP, através da nossa API:
$content =
file_get_contents("https://api.webscrapingapi.com/v1?pi_key=YOUR_API_KEY&url=". urlencode('https://httpbin.org/ip'));
echo $content;Conclusão
Parabéns por ter chegado ao fim! Agora já deve ter tudo o que precisa para criar o seu Web Scraper com PHP. Embora neste artigo tenhamos explorado apenas a biblioteca simple_html_dom, pode experimentar outras bibliotecas populares e ver por si mesmo qual delas se adequa melhor às suas necessidades.
Lembre-se de que os sites estão em constante mudança e os seus dados podem ser atualizados da noite para o dia. Para contornar esta situação, pode utilizar seletores mais específicos. É claro que isso não garante que o seu scraper funcione para sempre, mas é um começo. É por isso que os web scrapers exigem atualizações contínuas e demoradas.
Se não lhe apetece dedicar todo esse tempo a pesquisar e a adaptar o seu código, pode sempre experimentar a versão de avaliação gratuita da WebScrapingAPI!




