O Web scraping é uma técnica poderosa para extrair dados de sítios Web e o Golang (Go) é uma linguagem excelente para esta tarefa. Conhecida por seu desempenho e eficiência, Go pode lidar com raspagem da web com facilidade. Então, como extrair dados da Web com Golang? Este guia irá guiá-lo através do processo de raspagem de páginas web usando Golang, cobrindo técnicas e dicas relacionadas.
Golang é bom para raspar dados da Web?
Antes de aprender mais sobre raspagem de dados da web com Golang, é importante entender por que escolher Golang para raspagem da web e quais vantagens ele oferece.
Golang é uma forte escolha para raspagem da Web devido ao seu alto desempenho, modelo de concorrência eficiente e biblioteca padrão robusta. Com a sua capacidade de lidar com vários pedidos em simultâneo utilizando goroutines e os seus pacotes incorporados para pedidos HTTP e análise HTML, o Go pode extrair eficientemente grandes volumes de dados. A sua simplicidade e capacidades de tratamento de erros simplificam ainda mais o processo de desenvolvimento, enquanto bibliotecas de terceiros como Colly e Goquery oferecem funcionalidades adicionais. Embora menos comum do que Python para raspagem da Web, as vantagens de Go tornam-na uma opção atraente para quem está familiarizado com a linguagem.
Configuração básica para extrair dados da Web com Golang
A extração de dados da Web com Go (Golang) envolve fazer solicitações HTTP para recuperar páginas da Web e, em seguida, analisar o conteúdo HTML para extrair as informações desejadas. Abaixo está um guia passo a passo para extrair dados da Web usando Go:
-
-
Configurar o ambiente
Em primeiro lugar, certifique-se de que o Go está instalado no seu sistema. Nenhuma das pessoas pode descarregá-lo a partir do site sítio Web oficial.
-
Instalando os pacotes necessários
São necessários alguns pacotes para ajudar com pedidos HTTP e análise de HTML. Os pacotes mais populares são net/http para pedidos HTTP e goquery para análise de HTML.
Obter um pacote específico executando como:
ir buscar github.com/PuerkitoBio/goquery
Escrever o raspador
Aqui está uma demonstração simples de como extrair dados de um site usando Golang:
pacote principal importar ( "fmt" "log" "net/http" "github.com/PuerkitoBio/goquery" ) func main() { // URL do sítio web a ser recolhido url := "https://example.com" // Faz um pedido HTTP GET res, err := http.Get(url) se err != nil { log.Fatal(err) } defer res.Body.Close() // Verificar o código de estado da resposta se res.StatusCode != 200 { log.Fatalf("Falha ao obter dados: %d %s", res.StatusCode, res.Status) } // Analisar o HTML doc, err := goquery.NewDocumentFromReader(res.Body) se err != nil { log.Fatal(err) } // Localizar e imprimir os dados doc.Find("h1").Each(func(index int, item *goquery.Selection) { título := item.Text() fmt.Println(título) }) }
Efetuar pedidos HTTP:
http.Get(url) efectua um pedido HTTP GET para o URL especificado.
res.Body.Close() garante que o corpo da resposta é fechado após a leitura.Analisar HTML:
goquery.NewDocumentFromReader(res.Body) analisa a resposta HTML e devolve um objeto goquery.Document.
Extração de dados:
doc.Find("h1").Each() encontra todos os elementos h1 no HTML e repete-os.
item.Text() extrai o conteúdo de texto de cada elemento h1. -
Executar o raspador
Guarde o código acima num ficheiro, por exemplo, main.go, e execute-o utilizando:
go run main.go
-
Considerações adicionais
Tratamento de erros: Sempre trate os erros adequadamente para garantir que seu raspador não falhe inesperadamente.
Respeitar robots.txt: Verifique o ficheiro robots.txt do sítio Web para se certificar de que está autorizado a fazer scraping.
Limitação de taxa: Implemente a limitação da taxa para evitar sobrecarregar o servidor com pedidos.
User-Agent: Defina um cabeçalho User-Agent personalizado para identificar o seu scraper , como por exemplo:
req, err := http.NewRequest("GET", url, nil)
se err != nil {
log.Fatal(err)
}
req.Header.Set("User-Agent", "Golang_Scraper/1.0")
cliente := &http.Client{}
res, err := cliente.Do(req)
se err != nil {
log.Fatal(err)
}
defer res.Body.Close()
// Analisar o HTML como antes
Técnicas avançadas para extrair dados da Web com Golang
Manipulação da paginação
Muitos sítios Web utilizam a paginação para dividir o conteúdo em várias páginas. Para extrair todos os dados, é necessário lidar com a paginação, efectuando pedidos a cada página sequencialmente.
Eis um exemplo de tratamento da paginação:
pacote principal
importar (
"fmt"
"log"
"net/http"
"strconv"
"github.com/PuerkitoBio/goquery"
)
func main() {
baseURL := "https://example.com/page/"
página := 1
para {
url := baseURL + strconv.Itoa(page)
res, err := http.Get(url)
se err != nil {
log.Fatal(err)
}
defer res.Body.Close()
se res.StatusCode != 200 {
log.Println("Não há mais páginas para ir buscar, parando.")
break
}
doc, err := goquery.NewDocumentFromReader(res.Body)
se err != nil {
log.Fatal(err)
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
título := item.Find(".title").Text()
fmt.Println(título)
})
página++
}
}
Manipulação de conteúdo renderizado em JavaScript
Alguns sites usam JavaScript para renderizar conteúdo dinamicamente. O Go não tem uma maneira integrada de executar JavaScript, mas você pode usar um navegador sem cabeça como o Chromedp.
go get -u github.com/chromedp/chromedp
Exemplo de utilização do Chromedp para extrair conteúdo com renderização JavaScript:
pacote principal
importar (
"context"
"fmt"
"log"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
var htmlContent string
err := chromedp.Run(ctx,
chromedp.Navigate("https://example.com"),
chromedp.OuterHTML("body", &htmlContent),
)
if err != nil {
log.Fatal(err)
}
fmt.Println(htmlContent)
}
Gerir sessões e cookies
Se um sítio Web exigir o início de sessão ou a gestão de sessões, pode tratar os cookies e as sessões utilizando o http.CookieJar.
Exemplo de gestão de cookies:
pacote principal
importar (
"fmt"
"log"
"net/http"
"net/http/cookiejar"
"github.com/PuerkitoBio/goquery"
)
func main() {
jar, _ := cookiejar.New(nil)
cliente := &http.Client{Jar: jar}
// Iniciar sessão e guardar os cookies
loginURL := "https://example.com/login"
loginForm := url.Values{}
loginForm.Set("username", "your_username")
loginForm.Set("password", "your_password")
res, err := cliente.PostForm(loginURL, loginForm)
se err != nil {
log.Fatal(err)
}
res.Body.Close()
// Aceder a uma página protegida
url := "https://example.com/protected-page"
res, err = cliente.Get(url)
se err != nil {
log.Fatal(err)
}
defer res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
se err != nil {
log.Fatal(err)
}
doc.Find(".protected-content").Each(func(index int, item *goquery.Selection) {
content := item.Text()
fmt.Println(conteúdo)
})
}
Aceleração e limitação de taxa
Para evitar ser bloqueado por sítios Web, implemente a limitação da taxa introduzindo atrasos entre os pedidos.
Exemplo de limitação de débito:
pacote principal
importar (
"fmt"
"log"
"net/http"
"time"
"github.com/PuerkitoBio/goquery"
)
func main() {
urls := []string{"https://example.com/page1", "https://example.com/page2"}
for _, url := range urls {
res, err := http.Get(url)
se err != nil {
log.Fatal(err)
}
defer res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
se err != nil {
log.Fatal(err)
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
título := item.Find(".title").Text()
fmt.Println(título)
})
// Atraso para evitar ficar bloqueado
time.Sleep(2 * time.Second)
}
}
Tratamento de pedidos AJAX
Alguns sítios Web carregam dados dinamicamente através de pedidos AJAX. É possível capturar e replicar estes pedidos utilizando ferramentas como as ferramentas de desenvolvimento do browser para encontrar os pontos finais da API.
Exemplo de obtenção de dados a partir de um ponto de extremidade da API AJAX:
pacote principal
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type Item struct {
Título string `json: "título"`
}
func main() {
url := "https://example.com/api/items"
res, err := http.Get(url)
se err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var items []Item
if err := json.NewDecoder(res.Body).Decode(&items); err != nil {
log.Fatal(err)
}
for _, item := range items {
fmt.Println(item.Title)
}
}
Manuseamento de Captchas e Mecanismos Anti-Scraping
Os sítios Web utilizam frequentemente CAPTCHAs e outros mecanismos anti-raspagem. Embora a resolução programática de CAPTCHAs seja complexa e muitas vezes contrária aos termos de serviço, é possível utilizar técnicas como a rotação de agentes de utilizador e proxies para evitar a deteção.
Exemplo de agentes de utilizador rotativos:
pacote principal
importar (
"fmt"
"log"
"net/http"
"math/rand"
"time"
)
func main() {
userAgents := []string{
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, como Gecko) Chrome/58.0.3029.110 Safari/537.3",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:54.0) Gecko/20100101 Firefox/54.0",
// Adicione mais agentes de utilizador aqui
}
cliente := &http.Client{}
rand.Seed(time.Now().UnixNano())
for i := 0; i < 5; i++ {
req, err := http.NewRequest("GET", "https://example.com", nil)
se err != nil {
log.Fatal(err)
}
req.Header.Set("User-Agent", userAgents[rand.Intn(len(userAgents))])
res, err := cliente.Do(req)
se err != nil {
log.Fatal(err)
}
res.Body.Close()
fmt.Println("Pedido enviado com user-agent:", req.Header.Get("User-Agent"))
}
}
Utilização de proxies
Para proteger ainda mais o seu IP de ser banido, pode utilizar proxies. Serviços como o OkeyProxy ou o MacroProxy fornecem soluções de proxy.
Como um dos melhores fornecedores de proxy, OkeyProxy é suportado por HTTP/HTTPS/SOCKS e fornece mais de 150 milhões de IPs residenciais reais, abrangendo mais de 200 países/áreas, que podem evitar a proibição de IP e garante a segurança, a fiabilidade e a estabilidade das ligações de rede.

Exemplo de utilização de um proxy para extração de dados com http.Client:
pacote principal
importar (
"fmt"
"log"
"net/http"
"net/url"
)
func main() {
proxyURL, _ := url.Parse("http://proxyusername:proxypassword@proxyserver:port")
transport := &http.Transport{
Proxy: http.ProxyURL(proxyURL),
}
cliente := &http.Client{Transport: transport}
res, err := cliente.Get("https://example.com")
se err != nil {
log.Fatal(err)
}
defer res.Body.Close()
fmt.Println("Estado da resposta:", res.Status)
}
Raspagem simultânea
Para acelerar a recolha de dados, pode utilizar goroutines para tratar vários pedidos em simultâneo. Isto é útil para a recolha de grandes conjuntos de dados.
Exemplo de raspagem simultânea com goroutines:
pacote principal
importar (
"fmt"
"log"
"net/http"
"sync"
"github.com/PuerkitoBio/goquery"
)
func scrape(url string, wg *sync.WaitGroup) {
adiar wg.Done()
res, err := http.Get(url)
se err != nil {
log.Println(err)
return
}
defer res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
se err != nil {
log.Println(err)
return
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
título := item.Find(".title").Text()
fmt.Println(título)
})
}
func main() {
urls := []string{
"https://example.com/page1",
"https://example.com/page2",
// Adicionar mais URLs
}
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go scrape(url, &wg)
}
wg.Wait()
}
Extração de dados de APIs
Muitos sítios Web oferecem APIs para aceder a dados. A utilização de APIs é muitas vezes mais fácil e mais eficiente do que a raspagem de HTML.
Exemplo de chamada a uma API:
pacote principal
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
func main() {
url := "https://api.example.com/data"
res, err := http.Get(url)
se err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var data map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
log.Fatal(err)
}
fmt.Println("Dados da API:", dados)
}
Armazenamento de dados
Dependendo dos seus requisitos, poderá ser necessário armazenar os dados extraídos numa base de dados ou num ficheiro. Aqui está um exemplo de escrita de dados num ficheiro CSV:
pacote principal
importar (
"encoding/csv"
"fmt"
"log"
"os"
"net/http"
"github.com/PuerkitoBio/goquery"
)
func main() {
ficheiro, err := os.Create("dados.csv")
se err != nil {
log.Fatal(err)
}
defer file.Close()
escritor := csv.NewWriter(ficheiro)
defer escritor.Flush()
urls := []string{"https://example.com/page1", "https://example.com/page2"}
for _, url := range urls {
res, err := http.Get(url)
se err != nil {
log.Fatal(err)
}
defer res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
se err != nil {
log.Fatal(err)
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
título := item.Find(".title").Text()
writer.Write([]string{title})
})
}
fmt.Println("Dados escritos em dados.csv")
}
Tratamento de erros e registo
O tratamento robusto de erros e o registo são essenciais para a resolução de problemas e manutenção de scrapers. Você pode usar os recursos de registro do Go ou bibliotecas externas como logrus para registro avançado.
Bibliotecas essenciais para Web Scraping em Golang
- CollyEstrutura de recolha de dados da Web poderosa e fácil de utilizar. Instalação: go get -u github.com/gocolly/colly
- Goquerybiblioteca do tipo jQuery para manipulação e consulta de HTML. Instalação: go get -u github.com/PuerkitoBio/goquery
- PedidoCliente HTTP simplificado para efetuar pedidos. Instalação: go get -u github.com/imroc/req
- GrequestsBiblioteca de pedidos HTTP de nível superior, semelhante à biblioteca Requests do Python.Instalação: go get -u github.com/levigross/grequests
- CromadopAutomação do navegador utilizando o protocolo Chrome DevTools Instalação: go get -u github.com/chromedp/chromedp
- VaraBiblioteca moderna de automatização do browser para Go, com ênfase na facilidade de utilização e nas funcionalidades modernas. Instalação: go get -u github.com/ysmood/rod
- Go-SeleniumUm cliente Selenium WebDriver para Go, útil para automatizar browsers. Instalação: go get -u github.com/tebeka/selenium
- ScollyUm invólucro à volta do Colly para simplificar a recolha de dados da web. Instalação: go get -u github.com/scolly/scolly
- BrowshotUm cliente Go para a API Browshot para tirar capturas de ecrã e recolher conteúdo de páginas web. Instalação: go get -u github.com/browshot/browshot-go
- Titereiro-goUma porta Go do Puppeteer, uma biblioteca Node para controlar o Chrome sem cabeça.Instalação: go get -u github.com/chromedp/puppeteer-go
- PedidosBiblioteca simples de pedidos HTTP inspirada na biblioteca Requests do Python. Instalação: go get -u github.com/deckarep/golang-set
- HttpproxyUm servidor proxy HTTP simples para Go, útil para encaminhar o tráfego de raspagem da Web. Instalação: go get -u github.com/henrylee2cn/httpproxy
- RastejandoUma biblioteca para construir rastreadores distribuídos da web. Instalação: go get -u github.com/whyrusleeping/crawling
- K6Embora seja principalmente uma ferramenta de teste de carga, o K6 pode ser utilizado para extrair dados da Web com as suas capacidades de scripting. Instalação: go get -u github.com/loadimpact/k6
- Net/httpA biblioteca padrão para efetuar pedidos HTTP em Go.Instalação: Integrada em Go, sem necessidade de instalação separada.
- Goquery-htmlOutra biblioteca de análise de HTML com melhorias baseadas no Goquery. Instalação: go get -u github.com/PuerkitoBio/goquery-html
- Cliente httpUm cliente HTTP de alto nível para Go, que oferece funcionalidades de pedido avançadas. Instalação: go get -u github.com/aymerick/raymond
Estas bibliotecas e ferramentas abrangem uma gama de funcionalidades, desde simples pedidos HTTP até à automatização total do navegador, o que as torna versáteis para diferentes necessidades de extração da Web.
Resumo
A extração de dados da Web com Golang oferece várias vantagens, incluindo eficiência de desempenho e facilidade de concorrência. As goroutines e os canais leves do Go permitem o tratamento de vários pedidos simultâneos com um mínimo de sobrecarga de recursos, tornando-o ideal para tarefas de extração de dados em grande escala. Além disso, a forte biblioteca padrão da Go suporta capacidades robustas de análise de HTTP e HTML, simplificando o desenvolvimento de aplicações de raspagem da Web eficientes e fiáveis. Essa combinação de velocidade, simultaneidade e ferramentas integradas torna o Golang uma escolha atraente para projetos de raspagem da Web que exigem alto desempenho e escalabilidade.