Como extrair dados da Web com Golang 2025

recolha de dados da web com o go

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:

    1. 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.

      golang
    2. 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.

    3. 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.

okeyproxy

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

  1. CollyEstrutura de recolha de dados da Web poderosa e fácil de utilizar. Instalação: go get -u github.com/gocolly/colly
  2. Goquerybiblioteca do tipo jQuery para manipulação e consulta de HTML. Instalação: go get -u github.com/PuerkitoBio/goquery
  3. PedidoCliente HTTP simplificado para efetuar pedidos. Instalação: go get -u github.com/imroc/req
  4. GrequestsBiblioteca de pedidos HTTP de nível superior, semelhante à biblioteca Requests do Python.Instalação: go get -u github.com/levigross/grequests
  5. CromadopAutomação do navegador utilizando o protocolo Chrome DevTools Instalação: go get -u github.com/chromedp/chromedp
  6. 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
  7. Go-SeleniumUm cliente Selenium WebDriver para Go, útil para automatizar browsers. Instalação: go get -u github.com/tebeka/selenium
  8. ScollyUm invólucro à volta do Colly para simplificar a recolha de dados da web. Instalação: go get -u github.com/scolly/scolly
  9. 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
  10. 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
  11. PedidosBiblioteca simples de pedidos HTTP inspirada na biblioteca Requests do Python. Instalação: go get -u github.com/deckarep/golang-set
  12. 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
  13. RastejandoUma biblioteca para construir rastreadores distribuídos da web. Instalação: go get -u github.com/whyrusleeping/crawling
  14. 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
  15. Net/httpA biblioteca padrão para efetuar pedidos HTTP em Go.Instalação: Integrada em Go, sem necessidade de instalação separada.
  16. Goquery-htmlOutra biblioteca de análise de HTML com melhorias baseadas no Goquery. Instalação: go get -u github.com/PuerkitoBio/goquery-html
  17. 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.

Comentários

Ainda não há comentários. Porque não inicias o debate?

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *