Voltar ao blogue
Guias
Raluca PenciucLast updated on Apr 22, 20269 min read

Web Scraping em Ruby: O Tutorial Definitivo

Web Scraping em Ruby: O Tutorial Definitivo

Não vamos tentar amenizar a situação: à medida que os anos passam, o volume de dados na Internet só vai continuar a aumentar. A situação está fora do controlo de qualquer pessoa, mas será isso realmente uma coisa má?

Especialmente na última década, o web scraping ganhou enorme popularidade. Para ter sucesso no mundo empresarial atual, as empresas precisam de estratégias adequadas, o que requer muita informação num curto espaço de tempo. Além disso, pode ser uma forma interessante para os programadores melhorarem as suas competências de programação E ajudarem a empresa.

Se faz parte da equipa Ruby, mas não tem muito a ver com web scraping, este artigo irá proporcionar-lhe um novo nicho para explorar: construir o seu próprio web scraper.

Compreender o web scraping

Tomemos como exemplo uma plataforma de comparação de preços. A sua função é obter o custo de uma grande variedade de artigos de vários retalhistas online. Mas porquê limitar-se a produtos físicos? Os setores da aviação e da hotelaria também se tornaram muito mais acessíveis ao consumidor, graças aos sites de comparação. Então, como funcionam estes sites ou aplicações mágicos? Através do web scraping, claro!

Provavelmente está agora a perguntar-se: «De que outra forma poderei utilizar estes dados?». Vamos então dar uma vista de olhos a algumas das aplicações práticas do web scraping:

Este artigo bem escrito que aborda o web scraping fornece descrições detalhadas e casos de utilização adicionais.

Os web scrapers não são fáceis de criar, mesmo que compreenda como funcionam e os potenciais benefícios que podem proporcionar. Existem muitas formas através das quais os sites podem identificar e bloquear o acesso de bots aos seus dados.

A título de exemplo, eis alguns:

  • Bloqueio geográfico: Podem ser-lhe apresentados resultados específicos da sua região quando solicita informações de outra área (por exemplo, preços de bilhetes de avião).
  • Bloqueio de IP: Um site pode bloquear ou tornar o seu acesso mais lento quando determina que está a fazer pedidos repetidos a partir de um determinado endereço IP;
  • Honeypots: Os humanos não conseguem ver os links honeypot, mas os bots conseguem; assim que os robôs caem na armadilha, o seu endereço IP é bloqueado;
  • CAPTCHAs: As pessoas conseguem resolver estes problemas lógicos simples com relativa rapidez, mas os scrapers muitas vezes têm dificuldade;

Não é tarefa fácil superar todos estes obstáculos. Não é assim tão difícil construir um bot simples, mas criar um excelente web scraper é um pouco mais desafiante. Por isso, na última década, as APIs para web scraping tornaram-se um dos temas mais quentes.

O conteúdo HTML de qualquer site pode ser recolhido utilizando a WebScrapingAPI, e todos os problemas que mencionámos anteriormente serão automaticamente resolvidos. Além disso, utilizamos a Amazon Web Services para garantir velocidade e escalabilidade. Parece interessante, certo? Bem, não fique só pelas palavras! Experimente você mesmo com as 5000 chamadas de API gratuitas que recebe como parte do período de avaliação gratuita da WebScrapingAPI.

Compreender a Web

É necessário compreender o Protocolo de Transferência de Hipertexto (HTTP) para compreender a Web. Este protocolo explica como um servidor e um cliente comunicam. Uma mensagem contém informações que descrevem o cliente e a forma como este lida com os dados: método, versão HTTP e cabeçalhos.

Para pedidos HTTP, os web scrapers utilizam o método GET para recuperar dados do servidor. Além disso, existem alguns métodos avançados, como POST e PUT. Os métodos HTTP estão detalhados aqui para sua referência.

Nos cabeçalhos HTTP, é possível encontrar uma variedade de informações adicionais sobre pedidos e respostas. Para o web scraping, estas são as que importam:

  • User-Agent: os web scrapers dependem deste cabeçalho para tornar as suas solicitações mais realistas; contém informações como a aplicação, o sistema operativo, o software e a versão.
  • Cookie: o servidor e a solicitação podem trocar informações confidenciais (como tokens de autenticação).
  • Referrer: contém o site de origem que o utilizador visitou; por isso, é essencial ter este facto em consideração.
  • Host: identifica o host ao qual se está a ligar.
  • Accept: fornece um tipo de resposta para o servidor (por exemplo, text/plain, application/json).

Compreender o Ruby

Ruby é uma linguagem de programação multiparadigma de alto nível que também é totalmente interpretável. Isto significa que o código do programa é armazenado em texto simples, que é transmitido ao interpretador que o executa.

Em 1995, Yukihiro Matsumoto (também conhecido como Matz na comunidade Ruby) combinou características de diferentes linguagens de programação, como Perl, Lisp e Smalltalk, para criar uma nova que se concentra na simplicidade e na produtividade.

É uma linguagem de programação de nicho, sendo a sua área natural as aplicações web. Aqui estão as vantagens significativas de que beneficia ao utilizar esta linguagem nos seus projetos:

  • Obtém resultados rapidamente. Em combinação com o framework Rails, pode criar software de forma relativamente rápida; é por isso que as startups preferem principalmente o Ruby para construir rapidamente os seus MVPs (Produto Mínimo Viável).
  • É bem desenvolvida e mantida pela crescente comunidade Ruby.
  • Ferramentas e bibliotecas úteis (chamadas gems) garantem que é fácil seguir as melhores práticas de codificação em quase todas as situações.

Por outro lado, estas vantagens não fazem do Ruby uma solução mágica e universal para todo o software novo. Pode também considerar estas características da linguagem antes de tomar uma decisão:

  • À medida que o seu tamanho cresce, as aplicações construídas com Ruby tornam-se mais lentas, o que causa problemas de escalabilidade.
  • A sua área natural são as aplicações web. Por isso, não é adequado para aplicações de desktop/móveis.
  • Como utiliza um interpretador, um código orientado a objetos poderá ser mais lento.

Criar o seu próprio web scraper

Agora podemos começar a falar sobre a extração de dados. Primeiro, precisamos de um site que forneça informações valiosas.

Passo 1: Configurar o ambiente

Para criar o nosso scraper web em Ruby, precisamos primeiro de nos certificar de que temos todos os pré-requisitos:

  • A versão estável mais recente do Ruby: consulte o guia de instalação oficial para escolher o melhor método para o seu sistema operativo.
  • Um IDE: neste guia, vamos usar o Visual Studio Code, pois é leve e não requer configurações adicionais, mas pode escolher o IDE que preferir.
  • Bundler: uma ferramenta Ruby de gestão de dependências (também chamada de gem);
  • Watir: uma gem baseada no Selenium utilizada para testes automáticos, uma vez que consegue imitar o comportamento do utilizador num navegador;
  • Webdrivers: uma gem recomendada pelo Watir que descarrega automaticamente o driver mais recente para uma instância do navegador;
  • Nokogiri: uma gem conhecida pela capacidade de facilitar a análise de páginas web. Consegue analisar HTML, XML, deteta documentos HTML corrompidos e oferece acesso a elementos através de seletores XPath e CSS3.

Depois de configurar o ambiente Ruby, crie um novo diretório em qualquer local do seu computador e abra-o com o IDE da sua preferência. Em seguida, execute o seguinte comando numa janela de terminal para instalar a nossa primeira gem:

> gem install bundler

Agora crie um ficheiro chamado Gemfile no diretório raiz do seu projeto. Aqui vamos adicionar o resto das gems como dependências:

source 'https://rubygems.org'

gem 'watir', '~> 6.19', '>= 6.19.1'
gem 'webdrivers', '~> 4.6'
gem 'nokogiri', '~> 1.11', '>= 1.11.7'

Agora volte à janela do terminal e execute o seguinte comando para instalar as gems que declarámos:

> bundle install

Configuração fantástica! Por fim, basta criar um ficheiro “scraper.rb” para guardar o código do nosso scraper web. O que quer que escrevamos aqui, podemos executar com o comando:

> ruby scraper.rb

Passo 2: Inspecione a página que pretende raspar

Ótimo, vamos continuar! Navegue até à página que pretende raspar e clique com o botão direito em qualquer lugar, depois selecione “Inspecionar elemento”. A consola do programador irá aparecer, onde deverá ver o HTML do site.

Passo 3: Envie um pedido HTTP e extraia o HTML

Agora, para obter esse HTML na nossa máquina local, temos de enviar uma solicitação HTTP usando o Watir para retornar o documento. Vamos voltar ao IDE e transformar essa ideia em código.

Primeiro, escreva as importações de que precisamos:

require 'watir'
require 'webdrivers'
require 'nokogiri'

Em seguida, inicializamos uma instância do navegador e navegamos até ao site que queremos extrair. Depois, acedemos ao HTML e passamo-lo para o construtor Nokogiri, que nos ajudará a analisar o resultado.

browser = Watir::Browser.new
browser.goto 'https://blog.eatthismuch.com/latest-articles/'
parsed_page = Nokogiri::HTML(browser.html)

File.open("parsed.txt", "w") { |f| f.write "#{parsed_page}" }

browser.close

Também gravámos o resultado num ficheiro de texto chamado “parsed.txt” para dar uma vista de olhos ao HTML. É importante fechar a ligação após receber a resposta, uma vez que o processo continuará a ser executado.

Passo 4: Extrair secções específicas

Portanto, temos um documento HTML, mas queremos dados, o que significa que devemos analisar a resposta anterior para obter informações legíveis por humanos.

Começando com pequenos passos, vamos extrair o título do site. Um facto notável sobre o Ruby é que tudo é um objeto, com muito poucas exceções, o que significa que mesmo uma simples string pode ter atributos e métodos.

Portanto, podemos simplesmente aceder ao valor do título do site através dos atributos do objeto parsed_page.

puts parsed_page.title

Continuando, vamos extrair todos os links do site. Para isso, usaremos um método mais genérico que analisa tags específicas, o método css.

links = parsed_page.css('a')
links.map {|element| element["href"]}

puts links

Também usamos o método map para manter apenas os links com um atributo href do HTML.

Vamos ver um exemplo mais realista. Precisamos de extrair os artigos do blogue, o seu título, endereço e meta descrição.

Se inspecionar um dos cartões de artigo, poderá ver que podemos obter o endereço e o título do artigo através dos atributos do link. Além disso, a meta descrição encontra-se numa tag <div> com um nome de classe específico.

É claro que existem muitas formas de realizar esta pesquisa. A que iremos utilizar consistirá em procurar todas as tags <div> com o nome de classe td_module_10 e, em seguida, percorrer cada uma delas para extrair as tags <a> e as tags internas com o nome de classe td-excerpt.

article_cards = parsed_page.xpath("//div[contains(@class, 'td_module_10')]")

article_cards.each do |card|
    title = card.xpath("div[@class='td-module-thumb']/a/@title")
    link = card.xpath("div[@class='td-module-thumb']/a/@href")
    meta = card.xpath("div[@class='item-details']/div[@class='td-excerpt']")
end

Sim, como já deve ter adivinhado, uma expressão XPath é o que faz o truque, porque estamos à procura de elementos HTML pelos seus nomes de classe e pelos seus ascendentes.

Passo 5: Exportar os dados para CSV

Este tipo de extração pode ser útil quando os dados devem ser transferidos para outra aplicação, um agregador de artigos no nosso caso. Assim, para o fazer, precisamos de exportar os dados analisados para um ficheiro externo.

Vamos criar um ficheiro CSV, uma vez que este pode ser facilmente lido por outra aplicação e aberto no Excel para processamento posterior. Primeiro, apenas mais uma importação:

require 'csv'

Depois, vamos criar o CSV no modo “append” e envolver o código anterior, pelo que agora o nosso scraper ficará assim:

CSV.open("articles.csv", "a+") do |csv|
    csv << ["title", "link", "meta"]

    article_cards = parsed_page.xpath("//div[contains(@class, 'td_module_10')]")
    article_cards.each do |card|

        title = card.xpath("div[@class='td-module-thumb']/a/@title")
        link = card.xpath("div[@class='td-module-thumb']/a/@href")
        meta = card.xpath("div[@class='item-details']/div[@class='td-excerpt']")

        csv << [title.first.value, link.first.value, meta.first.text.strip]
    end
end

Ótimo, é tudo! Agora podemos ver todos os dados analisados de uma forma clara, simples e fácil de partilhar.

Conclusão e alternativas

Concluímos agora o nosso tutorial. Parabéns! Esperamos que este artigo lhe tenha dado muita informação sobre web scraping e o tenha ajudado a compreendê-lo melhor.

Obviamente, esta tecnologia pode fazer muito mais do que alimentar agregadores de artigos. O segredo está em encontrar os dados certos e analisá-los para descobrir novas possibilidades.

No entanto, como referi no início do artigo, os web scrapers enfrentam inúmeros desafios. Além de impulsionar o seu negócio, é uma excelente oportunidade de aprendizagem para os programadores resolverem problemas utilizando os seus próprios web scrapers. No entanto, poderá querer reduzir custos se precisar de concluir um projeto (tempo, dinheiro, pessoal).

Uma API dedicada a resolver estes problemas será sempre mais fácil de utilizar. Mesmo quando existem obstáculos como a renderização de Javascript, proxies, CAPTCHAs e outros fatores de bloqueio, a WebScrapingAPI supera todos eles e oferece uma experiência personalizável. Se ainda estiver indeciso, porque não experimentar a opção de avaliação gratuita?

Sobre o autor
Raluca Penciuc, Desenvolvedor Full-Stack @ WebScrapingAPI
Raluca PenciucDesenvolvedor Full-Stack

Raluca Penciuc é programadora Full Stack na WebScrapingAPI, onde desenvolve scrapers, aperfeiçoa estratégias de evasão e procura formas fiáveis de reduzir a deteção nos sites-alvo.

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.