O guia definitivo sobre como iniciar a raspagem da Web com Go
Sorin-Gabriel Marica em 14 de outubro de 2022
O Web scraping com Go é uma óptima forma de criar um scraper rápido e poderoso. Isto deve-se ao facto de GoLang ser uma das melhores linguagens de programação que se pode utilizar para a concorrência. Mas antes de começar, tenho de lhe dizer mais sobre o que é o Web scraping e como pode ajudá-lo.
O Web scraping é o processo de extração de dados de sítios Web. Este processo pode ser efectuado manualmente, mas esta abordagem não é recomendada quando se lida com uma grande quantidade de dados. Neste artigo, vamos explorar como pode construir o seu próprio Web scraper automatizado a partir do zero com Go.
Se é novo nesta área, pode perguntar-se quais são alguns dos casos de utilização do Web Scraping. Aqui está uma pequena lista com alguns dos mais comuns:
- Ferramentas de comparação de preços - É possível criar muitas ferramentas utilizando um raspador Web. Uma das mais comuns e úteis é uma ferramenta de comparação de preços. Uma ferramenta deste género recolhe os preços de um produto de várias fontes e apresenta a melhor oferta possível.
- Aprendizagem automática - Se quiser construir um modelo utilizando a aprendizagem automática, precisará de um conjunto de dados de treino. Embora por vezes seja possível encontrar conjuntos de dados existentes que podem ser utilizados, muitas vezes é necessário fazer algum trabalho extra e obter os dados de que necessita.
- Pesquisa de mercado - Um terceiro caso de utilização é a recolha de informações da Internet para descobrir quem são os seus concorrentes e o que estão a fazer. Desta forma, pode acompanhar ou manter-se à frente da concorrência, tendo conhecimento de qualquer nova funcionalidade que possam ter acrescentado.
O que é necessário para extrair dados com o go
Antes de começarmos, precisa de poder executar código GoLang na sua máquina. Para isso, tudo o que precisa é de instalar o Go, se ainda não o tiver feito. Pode encontrar mais detalhes sobre como instalar o Go e como verificar se o tem instalado aqui.
A outra coisa que vai precisar é de um IDE ou de um editor de texto à sua escolha, onde vamos escrever o código. Eu prefiro usar o Visual Studio Code, mas pode usar o que achar melhor.
E é tudo. Bastante simples, não? Agora vamos mergulhar no tópico principal deste artigo, o web scraping com go.
Construir um web scraper usando Go
Para construir o nosso scraper, precisamos primeiro de um objetivo, um conjunto de dados que queremos recolher de uma fonte específica. Assim, como tópico para o nosso scraper, escolhi recolher os downloads semanais dos primeiros pacotes do npmjs.com que utilizam a palavra-chave "framework". Pode encontrá-los nesta página: https://www.npmjs.com/search?q=keywords:framework&page=0&ranking=optimal)
Inspecionar o conteúdo da página que pretende extrair
Para fazer scraping corretamente, antes de começar a extrair os dados, é necessário ver onde estão os dados. Com isto quero dizer que terá de construir os selectores HTML para consultar os dados, com base na estrutura HTML da página.
Para ver a estrutura HTML da página, pode utilizar as ferramentas de programação disponíveis na maioria dos browsers modernos. No Chrome, pode fazê-lo na página clicando com o botão direito do rato no elemento que pretende extrair e clicando em "Inspecionar página". Depois de fazer isso, verá algo como isto:

Com base no HTML que pode ver à direita (a janela de inspeção), podemos agora construir os selectores que vamos utilizar. A partir desta página, precisamos apenas dos URLs de cada um dos pacotes.
By looking over the HTML, we can see that the css classes used by the website are code generated. This makes them not reliable for scraping so we will use the html tags instead. On the page we can see that the packages are in <section> tags and that the link to the package is in the first div from the first div of the section.
Knowing this we can build the following selector to extract the links of all the packages: section > div:first-child > div:first-child a. Before trying it in code, we can test the selector from the developer tools of the browser. To do this go to the console tab and run document.querySelectorAll("{{ SELECTOR }}"):

Ao passar o cursor por cima de cada um dos elementos da lista de modelos devolvidos, podemos ver que são exatamente os que procurávamos, pelo que podemos utilizar este seletor.
Raspagem de uma página usando Go
Estamos finalmente a começar a construir o scraper! Para o fazer, deves primeiro criar uma pasta onde colocaremos todo o nosso código. Em seguida, é necessário abrir uma janela de terminal, seja a partir do seu IDE ou do seu sistema operativo, e ir para a nossa pasta.
Para abrir um terminal na pasta, utilizando o Visual Studio Code, pode clicar em Terminal -> New Terminal (na barra superior).

Agora que temos o nosso terminal aberto, é altura de inicializar o projeto. Para isso, basta executar o comando:
go mod init webscrapingapi.com/my-go-scraper
Isto criará na tua pasta um ficheiro chamado go.mod com o seguinte conteúdo:
módulo webscrapingapi.com/my-go-scraper
go 1.19
Para fazer o pedido à página e extrair os selectores do HTML, vamos utilizar o Colly, um pacote GoLang(consulte a documentação do Colly para mais informações). Para instalar este pacote, é necessário executar
ir buscar github.com/gocolly/colly
Agora que temos tudo preparado, tudo o que precisamos de fazer é criar o nosso ficheiro main.go e escrever algum código. O código para extrair todos os links da primeira página dos frameworks npmjs é o seguinte:
package main
import (
"fmt"
"github.com/gocolly/colly"
)
func scrape() {
c := colly.NewCollector()
// Find and print all links
c.OnHTML("section > div:first-child > div:first-child a", func(e *colly.HTMLElement) {
fmt.Println(e.Attr("href"))
})
c.Visit("https://www.npmjs.com/search?q=keywords:framework&page=0&ranking=optimal")
}
func main() {
scrape()
}
Se isto parecer difícil de ler à primeira vista, não se preocupe, pois nos parágrafos seguintes explicaremos tudo.
Todo arquivo golang deve começar com o nome do pacote e as importações que o Go vai usar. Neste caso, os dois pacotes que usamos são o "fmt" para imprimir os links que raspamos, e o "Colly" (para a raspagem propriamente dita).
Na parte seguinte, criámos a função scrape() que se encarrega de recolher as ligações de que precisamos. Para isso, a função visita a primeira página e espera encontrar o seletor que decidimos. Quando aparece um elemento desse seletor, imprime o atributo href desse elemento.
A última parte é a função main, que é a função que é chamada sempre que executamos um script golang. Para executar o código anterior, execute main.go a partir do seu terminal, e deverá obter o seguinte resultado:

Como pode ver, o atributo href tem caminhos relativos para as ligações, pelo que teremos de o prefixar com o url do npmjs.
Use a concorrência do GoLang para obter eficiência
Uma das caraterísticas mais legais do GoLang são as GoRoutines. GoRoutines são threads simples e leves gerenciadas pelo runtime Go. O que é ótimo sobre isso é que Go pode nos ajudar a raspar muitas urls ao mesmo tempo com uma velocidade relâmpago.
Anteriormente, extraímos os links para os primeiros 20 pacotes sob a palavra-chave "framework" no npmjs.com. Agora vamos tentar extrair todos esses links ao mesmo tempo e extrair os downloads semanais de cada um deles. Para fazer isso, usaremos GoRoutines e WaitGroups.
Aqui está o código final para extrair os downloads semanais usando as goroutines:
package main
import (
"fmt"
"github.com/gocolly/colly"
"sync"
)
func scrapeWeeklyDownloads(url string, wg *sync.WaitGroup) {
defer wg.Done()
c := colly.NewCollector()
// Find and print the weekly downloads value
c.OnHTML("main > div > div:last-child > div:not([class]) p", func(e *colly.HTMLElement) {
fmt.Println(fmt.Sprintf("%s - %s", url, e.Text))
})
c.Visit(url)
}
func scrape() {
c := colly.NewCollector()
var wg sync.WaitGroup
// Find and print all links
c.OnHTML("section > div:first-child > div:first-child a", func(e *colly.HTMLElement) {
wg.Add(1)
go scrapeWeeklyDownloads(fmt.Sprintf("%s%s", "https://www.npmjs.com", e.Attr("href")), &wg)
})
c.Visit("https://www.npmjs.com/search?q=keywords:framework&page=0&ranking=optimal")
wg.Wait()
}
func main() {
scrape()
}
Agora vamos discutir o que foi adicionado ao nosso código anterior. Primeiro, você vai notar que temos um novo pacote importado chamado "sync". Isto vai ajudar-nos a usar rotinas golang e esperar que as threads terminem, antes de parar a execução do programa.
A próxima coisa adicionada é a nova função chamada "scrapeWeeklyDownloads". Esta função aceita dois parâmetros: o url do link que vamos extrair e um ponteiro WaitGroup. O que esta função faz é visitar o url dado e extrair os downloads semanais (usando o seletor main > div > div:last-child > div:not([class]) p).
As últimas alterações que irá notar foram na função scrape, onde criámos um WaitGroup utilizando var wg sync.WaitGroup. Aqui, para cada link da página de pacotes, usamos wg.Add(1) e depois criamos um GoRoutine que chama a função scrapeWeeklyDownloads. No final da função, a instrução wg.Wait() faz o código esperar até que todas as GoRoutines terminem de ser executadas.
Para obter mais informações sobre WaitGroups, consulte este exemplo do golang.
Porquê GoRoutines e WaitGroups?
Usando concurrency em golang com GoRoutines e WaitGroups podemos criar um scraper muito rápido. Executando o exemplo de código anterior, o scraper retornará a página e os downloads semanais de cada pacote. Mas, como estamos usando multi threading, a ordem em que essas informações serão exibidas é desconhecida (já que as threads executam em velocidades diferentes)
Se estiver a executar o código utilizando linux ou windows subsystem linux (wsl), pode utilizar time go run main.go para ver o tempo de execução de todo o script. Para mim, o tempo de execução é algo em torno de 5 a 6 segundos. Isto é muito rápido, considerando que estamos a fazer scraping de 21 páginas (Primeiro a página com os pacotes e depois as páginas de cada um dos pacotes).
Outros obstáculos
A maior parte dos "scrapers" conta normalmente com um simples pedido HTTP à página, para obter o conteúdo de que necessita. Esta solução é boa, mas por vezes os sítios Web apresentam a sua informação através de renderização javascript. Isto significa que o sítio Web mostra primeiro apenas uma parte do seu conteúdo, carregando o resto dinamicamente através de javascript.
Para fazer scrape dessas páginas, é preciso usar o chromedriver e controlar um navegador chrome real. Embora existam algumas opções para fazer isso em Golang, você precisará fazer alguma pesquisa extra para este tópico.
Mesmo com a cobertura da renderização de javascript, ainda existem alguns obstáculos extra quando se faz scraping de um sítio Web. Alguns sítios Web podem utilizar detecções anti-bot, bloqueios de ip ou captchas para impedir que os bots recolham o seu conteúdo. Para continuar a fazer scraping desses sítios Web, pode tentar utilizar algumas dicas e truques para fazer scraping da Web, como tornar o seu scraper mais lento e agir de forma mais humana.
Mas, se quiser manter o seu scraper rápido e ultrapassar estes obstáculos de uma forma fácil, pode utilizar a WebScrapingAPI. O WebScrapingAPI é uma API concebida para o ajudar com o scraping, rodando o seu IP e evitando detecções antibot. Desta forma, pode continuar a utilizar a velocidade relâmpago que o GoLang proporciona e recolher os seus dados num instante.
Conclusão sobre Web Scraping com Go
O Web Scraping é uma forma agradável e rápida de extrair dados da Internet e pode ser utilizado para muitos casos de utilização diferentes. Pode optar por extrair dados para o seu modelo de aprendizagem automática ou criar uma aplicação de raiz utilizando os dados extraídos.
GoLang é uma das melhores soluções que existem quando se trata de concorrência. Usando GoLang e Colly pode construir um scraper rápido que trará os seus dados num instante. Isto torna o web scraping com Go muito fácil e eficiente quando se habitua à sintaxe de Go
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

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!


Aprenda a raspar tabelas HTML com Golang para uma poderosa extração de dados. Explore a estrutura das tabelas HTML e crie um raspador da Web usando a simplicidade, a simultaneidade e a robusta biblioteca padrão do Golang.


Saiba como usar proxies com node-fetch, um cliente HTTP JavaScript popular, para criar raspadores da Web. Entenda como os proxies funcionam na raspagem da Web, integre proxies com node-fetch e crie um raspador da Web com suporte a proxy.
