Raspagem da Web com Ruby – Guia Completo

Quer seja um principiante ou um programador experiente, este guia lhe fornecerá as competências e os conhecimentos necessários para se tornar um raspador da web eficaz em Ruby.
14 min read
Web Scraping with Ruby

TL;DR: Este tutorial vai ensinar-lhe como extrair dados de um sítio em Ruby e porque é que é uma das linguagens mais eficazes para raspagem.

Este guia abordará:  

O Ruby é bom para a raspagem da web?

Ruby é uma linguagem de programação interpretada, de código aberto e de tipagem dinâmica que suporta o desenvolvimento funcional, orientado a objetos e processual. Foi concebido para ser simples, com uma sintaxe elegante que é fácil de escrever e natural de ler. O seu foco na produtividade tornou-o uma escolha popular em várias aplicações, incluindo a raspagem da web.

Em particular, o Ruby é uma excelente escolha para a raspagem devido à vasta gama de bibliotecas de terceiros disponíveis. São as chamadas “gemas” e há uma para quase todas as tarefas. Quando se trata de recuperar informações da web de forma programática, existem gemas para descarregar páginas, analisar o seu conteúdo HTML e extrair dados das mesmas.

Em resumo, a raspagem da web em Ruby não é apenas possível, mas também fácil graças às muitas bibliotecas disponíveis. Vamos descobrir quais são as mais populares!

As melhores gemas de Ruby para raspagem da web

Aqui estão as três melhores bibliotecas de raspagem da web para Ruby:

  • Nokogiri(鋸): Uma biblioteca robusta e flexível de análise de HTML e XML com uma API completa para atravessar e manipular documentos HTML/XML, facilitando a extração de dados relevantes dos mesmos.
  • Mechanize: Uma biblioteca com funcionalidade de navegador sem cabeça que fornece uma API de alto nível para automatizar a interação com sítios web. Pode armazenar e enviar cookies, lidar com redireccionamentos, seguir links e enviar formulários. Além disso, fornece um histórico para manter o registo dos sítios visitados.
  • Selenium: Uma ligação de Ruby da estrutura mais popular para executar testes automatizados em páginas web. Pode dar instruções a um navegador para interagir com um sítio web como faria um usuário humano. Esta tecnologia desempenha um papel fundamental para contornar as soluções antibot e os sítios de raspagem que dependem do JavaScript para renderizar ou recuperar dados.

Pré-requisitos

Antes de escrever algum código, é necessário instalar o Ruby no seu computador. Siga o guia abaixo relacionado com o seu sistema operativo.

Instalar o Ruby no macOS

 

Por padrão, o Ruby está incluído no macOS desde a versão 10.11 (El Capitan), lançada em 2015. Considerando que o macOS depende nativamente do Ruby para fornecer algumas funcionalidades, você não deve tocá-lo. A atualização da versão nativa do Ruby com brew install ruby ou update ruby mac não é recomendada, pois pode quebrar algumas funcionalidades incorporadas.

Instalar o Ruby no Windows

 

Descarregue o pacote RubyInstaller, inicie-o e siga o assistente de instalação para configurar o Ruby. Poderá ser necessário reiniciar o sistema. A partir do Windows 10, também pode utilizar o Subsistema Windows para Linux para instalar o Ruby, seguindo as instruções abaixo.

Instalar o Ruby no Linux

 

A melhor maneira de configurar um ambiente Ruby no Linux é instalá-lo através de um gestor de pacotes.

Em Debian e Ubuntu, iniciar:

sudo apt-get install ruby-full

Noutras distribuições, o comando de terminal a executar é diferente. Consulte o guia no sítio oficial para ver todos os sistemas de gestão de pacotes suportados.

Independentemente do seu sistema operativo, pode agora verificar se o Ruby está a funcionar com:

ruby -v

Isso deve imprimir algo como:

ruby 3.2.2 (2023-03-30 revision e51014f9c0)

Ótimo! Está agora pronto para começar a raspar a web com Ruby!

Construir um raspador da web em Ruby

Nesta secção, verá como criar um raspador da web com Ruby. Este script automatizado recupera dados da página inicial da Bright Data. Em detalhe, irá:  

  • Ligar ao sítio de destino
  • Selecionar os elementos HTML de interesse no DOM
  • Extrair dados dos mesmos
  • Converter os dados extraídos em formatos fáceis de explorar, como CSV e JSON

No momento em que escrevem, isso é o que os usuários veem quando visitam a página web de destino:

Tenha em conta que a página inicial da BrightData muda frequentemente e poderá não ser a mesma quando você ler este artigo.

O objetivo específico da raspagem é obter a informação do caso de utilização contida nos seguintes cartões:  

Página inicial da BrightData

Siga o tutorial passo-a-passo abaixo e aprenda a fazer raspagem da web com Ruby!

Passo 1: Inicializar um projeto em Ruby

 

Antes de começar, é necessário configurar o seu projeto em Ruby. Inicie o terminal, crie a pasta do projeto e insira-a com:

mkdir ruby-web-scraper

cd ruby-web-scraper

O diretório ruby-web-scraper conterá seu raspador.

Em seguida, inicialize um arquivo scraper.rb dentro da pasta do projeto com o seguinte conteúdo:

puts "Hello, World!"

O trecho acima é o script de Ruby mais fácil possível.

Verifique se funciona, executando-o no seu terminal:

ruby scraper.rb

Isto deve imprimir esta mensagem:

Hello, World!

Está na altura de importar o seu projeto para o seu IDE e começar a definir alguma lógica avançada de raspagem com Ruby! Neste guia, verá como configurar o Visual Studio Code (VS Code) para desenvolvimento em Ruby. Ao mesmo tempo, qualquer outro IDE de Ruby serve.

Uma vez que o VS Code não suporta o Ruby nativamente, primeiro tem de adicionar a extensão de Ruby. Inicie o Visual Studio Code, clique no ícone “Extensões” na barra esquerda e escreva “Ruby” na entrada de pesquisa na parte superior.

Extensões

Clique no botão “Instalar” no primeiro elemento para adicionar recursos de realce de Ruby ao VS Code. Aguarde até que o plug-in seja adicionado ao IDE. Em seguida, abra a pasta ruby-web-scraper comFicheiro“, “Abrir pasta…”  

Clique no ficheiro scraper.rb na barra “EXPLORER” para começar a editar o ficheiro:  

ficheiro scraper.rb EXPLORER

Passo 2: Escolher a biblioteca de raspagem

 

Construir um raspador da web em Ruby torna-se mais fácil com a biblioteca certa. Por este motivo, deve adotar uma das gemas apresentadas anteriormente. Para descobrir qual a biblioteca Ruby de raspagem da web que melhor se adequa aos seus objetivos, tem de passar algum tempo a analisar o seu sítio alvo.

Por esse motivo, visite a página de destino em seu navegador, clique com o botão direito do rato em um local em branco no fundo e clique na opção “Inspecionar“. Isto irá abrir as ferramentas de desenvolvimento do seu navegador. No Chrome, aceda ao separador “Rede” e explore a seção “Fetch/XHR“.  

ab, e explore a seção "Fetch/XHR"

Como você pode observar na captura de tela acima, há apenas sete pedidos AJAX. Se analisar cada chamada XHR, verificará que não envolve dados significativos. Isso significa que a página de destino não recupera conteúdo no momento da renderização. Assim, o documento HTML devolvido pelo servidor já contém todos os dados a mostrar aos usuários.  

Isso prova que a página web de destino não usa JavaScript para fins de recuperação ou renderização de dados. Em outras palavras, você não precisa de uma gema com recursos de navegador sem cabeça para executar a raspagem da web. Você ainda pode usar Mecanize ou Selenium, mas eles só adicionariam algumas despesas gerais de desempenho. Afinal, executam uma instância do navegador nos bastidores, o que consome recursos.

Em resumo, deve optar por um analisador HTML/XML simples como o Nokogiri. Instale-o através da gema nokogiri com:

gem install nokogiri

Pode então importar a biblioteca adicionando a seguinte linha no topo do seu ficheiro scraper.rb:

require "nokogiri"

Certifique-se de que o seu IDE de Ruby não reporte erros, e pode agora raspar alguns dados em Ruby!

Passo 3: Utilizar o HTTParty para obter a página de destino

 

Para analisar o documento HTML da página de destino, primeiro é necessário descarregá-lo através de um pedido HTTP GET. O Ruby vem com um cliente HTTP incorporado chamado Net::HTTP, mas a sua sintaxe é um pouco complicada e não intuitiva. Em vez disso, deve utilizar HTTParty, que é a biblioteca Ruby mais popular para efetuar pedidos HTTP.

Instale-o através da gema httparty com:

gem install httparty

Then, import it in the scraper.rb file:

require "httparty"

Use HTTParty to connect to the target page with:

response = HTTParty.get("https://brightdata.com/")

O método get() permite-lhe efetuar um pedido GET ao URL passado como parâmetro. O campo response.body conterá o documento HTML devolvido pelo servidor.

Note-se que o pedido HTTP efetuado através de get() pode falhar. Quando isso acontece, o HTTParty levanta uma exceção e detém a execução do seu script com um erro. Podem existir inúmeras razões por detrás de uma falha, mas o que normalmente acontece é que uma tecnologia antibot adotada pelo sítio alvo intercetou e bloqueou os seus pedidos automáticos. Os sistemas antirraspagem mais básicos tendem a filtrar os pedidos sem um cabeçalho HTTP de Usuário-Agente válido. Consulte o nosso artigo para saber mais sobre Usuários-Agentes para a raspagem da Web.  

Como qualquer outro cliente HTTP, o HTTParty utiliza um Usuário-Agente de reserva. Este é geralmente muito diferente dos agentes utilizados pelos navegadores populares, tornando os seus pedidos facilmente detetáveis por soluções antibot. Para evitar ser bloqueado por causa disso, pode especificar um Usuário-Agente válido no HTTParty da seguinte forma:

response = HTTParty.get("https://brightdata.com/", {

  headers: { "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"},

})

O pedido efetuado através desse get() aparecerá agora ao servidor como vindo do Google Chrome 112.

Isto é o que o scraper.rb contém atualmente:  


require "nokogiri"
require "httparty"

# get the target page
response = HTTParty.get("https://brightdata.com/", {
  headers: {
    "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
  },
})

# scraping logic...

Passo 4: Analisar o documento HTML com o Nokogiri

 

Para analisar o documento HTML associado à página web de destino, passe o seu conteúdo à função de HTML() Nokogiri:

doc = Nokogiri::HTML(response.body)

Pode agora utilizar a API de manipulação e exploração do DOM oferecida através da variável doc. Especificamente, os dois métodos mais importantes para selecionar elementos HTML são:

  • xpath(): Retorna a lista de nós HTML que correspondem à consulta XPath
  • css(): Devolve a lista de nós HTML que correspondem ao seletor de CSS passado como parâmetro

Ambas as abordagens funcionam, mas as consultas CSS são normalmente a forma mais fácil de expressar o que se procura.

Passo 5: Definir os seletores de CSS para os elementos HTML de interesse

 

Para compreender como selecionar os elementos HTML desejados na página de destino, é necessário analisar o DOM. Visite a página inicial da Bright Data no seu navegador, clique com o botão direito do rato num dos cartões de interesse e selecione “Inspecionar“:  

Inspecionar

Reserve algum tempo para explorar o código HTML na seção DevTools. Cada cartão de caso de utilização é um

que contém:

  1. Um <figure> com um elemento HTML <img> que mostra a imagem associada ao sector e um elemento <a> que contém o URL da página do sector.  
  2. Um elemento HTML <div> que armazena o nome do sector numa etiqueta <a>.  

O objetivo da extração de dados do raspador de Ruby é obter o URL da imagem, o URL da página e o nome do sector de cada cartão.

Para definir bons seletores de CSS, preste atenção às classes de CSS atribuídas aos nós DOM de interesse. Verificará que pode obter todos os cartões de casos de utilização com o seletor de CSS a seguir:

.section_cases_row_col_item

Dado um cartão, é possível selecionar os nós que armazenam os dados relevantes dos seus filhos <figure> e <div> com:  

  1. figure img
  2. figure a
  3. .elementor-image-box-content a

Passo 6: Raspar dados de uma página web com Nokogiri

 

Agora é necessário utilizar o Nokogiri para obter os dados desejados da página HTML de destino.

Antes de mergulhar na lógica de raspagem de dados, não se esqueça de que você precisa de algumas estruturas de dados onde armazenar os dados coletados. Para o efeito, é possível definir uma classe UseCase numa única linha com um Struct:

UseCase = Struct.new(:image, :url, :name)

Em Ruby, um Struct permite-lhe agrupar um ou mais atributos na mesma classe de dados. A estrutura acima tem os três atributos correspondentes às informações a obter de cada cartão de caso de utilização.

Inicialize uma matriz vazia de UseCase e implemente a lógica de raspagem de dados para a preencher:  

# initialize the list of objects

# that will store all retrieved data

use_cases = []

# select all use case HTML elements

use_case_cards = doc.css(".section_cases_row_col_item")

# iterate over the HTML cards

use_case_cards.each do |use_case_card|

    # extract the data of interest

    image = use_case_card.at_css("figure img").attribute("data-lazy-src").value

    url = use_case_card.at_css("figure a").attribute("href").value

    name = use_case_card.at_css(".elementor-image-box-content a").text

    # instantiate an UseCase object with the

    # collected data

    use_case = UseCase.new(url, image, name)

    # add the UseCase instance to the array

    # of scraped objects

    use_cases.push(use_case)

end

O trecho acima seleciona todos os cartões de caso de uso e itera sobre eles. Em seguida, raspa de cada cartão o URL da imagem, o URL da página do setor e o nome com at_css(). Esta é uma função de Nokogiri que devolve o primeiro elemento que corresponde à consulta CSS e representa um atalho para:

image = use_case_card.css("figure img").first.attribute("data-lazy-src").value

Finalmente, usa os dados recuperados para instanciar um novo objeto UseCase e adicioná-lo à lista.

O raspagem da web utilizando Ruby com Nokogiri é bastante simples. Com attribute(), pode selecionar um atributo do elemento HTML atual. Em seguida, o campo de valor permite-lhe obter o seu valor. Da mesma forma, o campo de texto devolve diretamente todo o texto contido no nó HTML atual como uma cadeia simples.

Agora, você pode ir além e raspar também as páginas do setor de casos de uso. Você pode seguir os links descobertos aqui e implementar uma nova lógica de raspagem adaptada aos mesmos. Bem-vindo ao mundo do rastejamento da web e da raspagem da web!  

Fantástico! Acabou de aprender como atingir os seus objetivos de raspagem com Ruby. No entanto, ainda há algumas lições a aprender.

Passo 7: Exportar os dados raspados

 

Após o each() loop, use_cases conterá os dados raspados em objetos de Ruby. Este não é o melhor formato para fornecer dados a outras equipas. Felizmente, o Ruby tem capacidades incorporadas de conversão para CSV e JSON. Saiba como exportar os dados recuperados para CSV e JSON.  

Para exportar CSV, importe a seguinte gema:

import "csv"

Faz parte da API estândar de Ruby e fornece uma interface completa para lidar com ficheiros e dados CSV.

Você pode aproveitá-la para exportar a matriz use_cases para um ficheiro .csv de saída, como se segue:

# populate the CSV output file

CSV.open("output.csv", "wb") do |csv|

  # write the CSV header

  csv << ["url", "image", "name"]

  # transfrom each use case scraped info to a

  # CSV record

  use_cases.each do |use_case|

    csv << use_case

  end

end

O trecho acima cria o ficheiro .csv de saída. Em seguida, o abre e o inicializa com o registo de cabeçalho. Depois, itera sobre a matriz use_cases e anexa-a ao ficheiro CSV. Ao utilizar o operador <<, o Ruby converte automaticamente cada instância de use_case numa matriz de cadeias de caracteres, conforme exigido pela classe CSV incorporada.

Tente executar o script com:  

ruby scraper.rb

Um ficheiro output.csv contendo os dados abaixo será produzido no diretório raiz do seu projeto:

Um ficheiro output.csv contendo os dados abaixo será produzido no diretório raiz do seu

Da mesma forma, pode exportar use_cases para output.json:  

# propulate the JSON output file

File.open("output.json", "wb") do |json|

  json << JSON.pretty_generate(use_cases.map { |u| Hash[u.each_pair.to_a] })

end

Isto irá gerar o seguinte ficheiro JSON:  

[

  {

    "image": "https://brightdata.com/use-cases/ecommerce",

    "url": "https://brightdata.com/wp-content/uploads/2022/07/E_commerce.svg",

    "name": "eCommerce "

  },

  // ...

  {

    "image": "https://brightdata.com/use-cases/data-for-good",

    "url": "https://brightdata.com/wp-content/uploads/2022/07/Data_for_Good_N.svg",

    "name": "Data for Good"

  }

]

Et voilà! Agora você já sabe como converter uma matriz de structs para CSV e JSON em Ruby!

Passo 8: Juntar tudo

 

Aqui está o código completo do raspador de Ruby:

# scraper.rb

require "nokogiri"

require "httparty"

require "csv"

# get the target page

response = HTTParty.get("https://brightdata.com/", {

  headers: {

    "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",

  },

})

# parse the HTML document retrieved with the GET request

doc = Nokogiri::HTML(response.body)

# define a class where to keep the scraped data

UseCase = Struct.new(:image, :url, :name)

# initialize the list of objects

# that will store all retrieved data

use_cases = []

# select all use case HTML elements

use_case_cards = doc.css(".section_cases_row_col_item")

# iterate over the HTML cards

use_case_cards.each do |use_case_card|

  # extract the data of interest

  image = use_case_card.at_css("figure img").attribute("data-lazy-src").value

  url = use_case_card.at_css("figure a").attribute("href").value

  name = use_case_card.at_css(".elementor-image-box-content a").text

  # instantiate an UseCase object with the

  # collected data

  use_case = UseCase.new(url, image, name)

  # add the UseCase instance to the array

  # of scraped objects

  use_cases.push(use_case)

end

# populate the CSV output file

CSV.open("output.csv", "wb") do |csv|

  # write the CSV header

  csv << ["url", "image", "name"]

  # transfrom each use case scraped info to a

  # CSV record

  use_cases.each do |use_case|

    csv << use_case

  end

end

# propulate the JSON output file

File.open("output.json", "wb") do |json|

  json << JSON.pretty_generate(use_cases.map { |u| Hash[u.each_pair.to_a] })

end

Em cerca de 50 linhas de código, é possível criar um script de raspagem em Ruby!

Conclusão

Neste tutorial, você entendeu porque o Ruby é uma ótima linguagem para raspar a Internet. Também teve a oportunidade de ver quais são as melhores bibliotecas de gemas de Ruby para raspagem da web, porquê e que funcionalidades oferecem. Em seguida, mergulhou em como usar o Nokogiri e a API padrão de Ruby para construir um raspador de Ruby que pode raspar um alvo do mundo real. Como você viu, a raspagem de dados com Ruby requer poucas linhas de código.

No entanto, não subestime os desafios existentes quando se trata de extrair dados de páginas web. É por esta razão que um número crescente de sítios tem vindo a implementar sistemas antibot e antirraspagem para proteger os seus dados. Estas tecnologias são capazes de detetar os pedidos efetuados pelo seu script de Ruby de raspagem e impedir o acesso ao sítio. Felizmente, é possível criar um raspador da web que pode contornar esses bloqueios com o IDE para Raspador da Web de última geração da Bright Data.

Não quer lidar com a raspagem da web, mas está interessado em dados da web? Explore os nossos conjuntos de dados prontos a utilizar.