O web scraping é uma técnica para extrair dados de sites e pode ser uma ferramenta poderosa para recolher informações da Internet. Este artigo irá abordar como extrair tabelas HTML com Golang, uma linguagem de programação popular conhecida pela sua simplicidade, suporte à concorrência e biblioteca padrão robusta.
Introdução
O que são tabelas HTML?
As tabelas HTML são um tipo de elemento em HTML (Hypertext Markup Language) utilizado para representar dados tabulares numa página web. Uma tabela HTML é composta por linhas e colunas de células que contêm texto, imagens ou outros elementos HTML. As tabelas HTML são criadas utilizando o elemento table e são estruturadas utilizando os elementos ‘<tr>’ (linha da tabela), ‘<td>’ (célula da tabela), ‘<th>’ (cabeçalho da tabela), ‘<caption>’, ‘<col>’, ‘<colgroup>’, ‘<tbody>’ (corpo da tabela), ‘<thead>’ (cabeçalho da tabela) e ‘<tfoot>’ (rodapé da tabela). Agora, vamos analisar cada um deles e aprofundar os detalhes:
- elemento table: Define o início e o fim de uma tabela HTML.
- Elemento tr (linha da tabela): Define uma linha numa tabela HTML.
- Elemento td (célula da tabela): Define uma célula numa tabela HTML.
- Elemento th (cabeçalho da tabela): Define uma célula de cabeçalho numa tabela HTML. As células de cabeçalho são apresentadas em negrito e centradas por predefinição e são utilizadas para identificar as linhas ou colunas da tabela.
- Elemento caption: Define uma legenda ou título para uma tabela HTML. A legenda é normalmente apresentada acima ou abaixo da tabela.
- Elementos col e colgroup: Definem as propriedades das colunas numa tabela HTML, tais como a largura ou o alinhamento.
- Elementos tbody, thead e tfoot: Definem as secções corpo, cabeçalho e rodapé de uma tabela HTML, respetivamente. Estes elementos podem ser utilizados para agrupar linhas e aplicar estilos ou atributos a uma secção específica da tabela.
Para uma melhor compreensão deste conceito, vamos ver como é uma tabela HTML:
À primeira vista, parece uma tabela normal e não conseguimos ver a estrutura com os elementos acima descritos. Isso não significa que eles não estejam presentes, significa que o navegador já analisou isso por nós. Para poder ver a estrutura HTML, é necessário ir um passo mais além e utilizar ferramentas de desenvolvimento. Pode fazê-lo clicando com o botão direito do rato na página, clicando em «Inspecionar», clicando na ferramenta «Selecionar elemento» e clicando no elemento (neste caso, a tabela) cuja estrutura HTML pretende ver. Depois de seguir estes passos, deverá ver algo semelhante a isto:
As tabelas HTML são frequentemente utilizadas para apresentar dados num formato estruturado e tabular, como para tabular resultados ou exibir o conteúdo de uma base de dados. Podem ser encontradas numa grande variedade de sites e são um elemento importante a ter em conta ao extrair dados da web.
Configuração
Antes de começarmos a extrair dados, precisamos de configurar o nosso ambiente Golang e instalar as dependências necessárias. Certifique-se de que tem o Golang instalado e configurado no seu sistema e, em seguida, crie um novo diretório de projeto e inicialize um ficheiro `go.mod`:
$ mkdir scraping-project
$ cd scraping-project
$ go mod init <NAME-OF-YOUR-PROJECT>$ touch main.go
Em seguida, precisamos de instalar uma biblioteca para efetuar pedidos HTTP e analisar HTML. Existem várias opções disponíveis, mas para este artigo iremos utilizar o pacote `net/http` da biblioteca padrão e o pacote golang.org/x/net/html para analisar HTML. Estes pacotes podem ser instalados executando o seguinte comando:
$ go get -u net/http golang.org/x/net/html
Agora que o nosso ambiente está configurado, estamos prontos para começar a construir o nosso scraper de tabelas HTML usando Golang.
Vamos começar a extrair
Agora que temos o nosso ambiente configurado, podemos começar a construir um scraper para extrair dados de uma tabela HTML. O primeiro passo é enviar uma solicitação HTTP para a página web que contém a tabela HTML que queremos extrair. Podemos usar a função `http.Get` do pacote `net/http` para enviar uma solicitação GET e recuperar o conteúdo HTML:
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
resp, err := http.Get("https://www.w3schools.com/html/html_tables.asp")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Read the response body and convert it to a string
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
html := string(body)
fmt.Println(html)
}Em seguida, podemos usar a função `goquery.NewDocumentFromReader` do pacote goquery para analisar o conteúdo HTML e extrair os dados de que precisamos. Como qualquer outro pacote Golang, é necessário instalá-lo primeiro da seguinte forma:
$ go get github.com/PuerkitoBio/goquery
E, em seguida, adicionar o código seguinte, que irá analisar o HTML da página:
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
log.Fatal(err)
}Agora que temos um analisador e um extrator de elementos para o nosso HTML, podemos tirar partido da funcionalidade `doc.Find()` do pacote Goquery, que nos permite encontrar os elementos específicos que procuramos, neste caso, uma tabela. Podemos utilizá-la da seguinte forma:
doc.Find("table").Each(func(i int, sel * goquery.Selection) {
// For sake of simplicity taking the first table of the page
if i == 0 {
// Looping through headers
headers: = sel.Find("th").Each(func(_ int, sel * goquery.Selection) {
if sel != nil {
fmt.Print(sel.Text())
fmt.Print(" ")
}
})
fmt.Println()
// Looping through cells
sel.Find("td").Each(func(index int, sel * goquery.Selection) {
if sel != nil {
fmt.Print(sel.Text())
fmt.Print(" ")
}
// Printing columns nicely
if (index + 1) % headers.Size() == 0 {
fmt.Println()
}
})
}
})É isso, agora já consegue extrair a tabela usando Golang e deverá conseguir vê-la no ecrã assim:
Como poderá notar, a estrutura pode ser bastante confusa e difícil de ler. A boa notícia é que pode fazer melhor do que isso e apresentar os dados de forma organizada num formato tabular, que é fácil de ler. Esta é uma tarefa perfeita para o pacote tablewriter, que pode instalar da seguinte forma:
$ go get github.com/olekukonko/tablewriter
Agora precisamos de fazer alguns ajustes no nosso código antes de passar as nossas informações para o tablewriter, tais como definir os cabeçalhos da tabela, as estruturas e armazená-los numa matriz. Deverá ficar mais ou menos assim:
package main
import (
"log"
"net/http"
"os"
"github.com/PuerkitoBio/goquery"
"github.com/olekukonko/tablewriter"
)
type Company struct {
Company string
Contact string
Country string
}
func main() {
resp, err := http.Get("https://www.w3schools.com/html/html_tables.asp")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Read the response body and convert it to a string
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
log.Fatal(err)
}
var companies []Company
doc.Find("table").Each(func(i int, sel *goquery.Selection) {
if i == 0 {
e := Company{}
sel.Find("td").Each(func(index int, sel *goquery.Selection) {
if index%3 == 0 {
e.Company = sel.Text()
}
if index%3 == 1 {
e.Contact = sel.Text()
}
if index%3 == 2 {
e.Country = sel.Text()
}
// Add the element to our array
if index != 0 && (index+1)%3 == 0 {
companies = append(companies, e)
}
})
}
})
table := tablewriter.NewWriter(os.Stdout)
// Setting our headers
table.SetHeader([]string{"Company", "Contact", "Country"})
for _, Company := range companies {
s := []string{
Company.Company,
Company.Contact,
Company.Country,
}
table.Append(s)
}
table.Render()
}Deve agora conseguir ver os dados apresentados neste formato:
Nesta altura, conseguiu criar um scraper em Golang que extrai uma página web e armazena e apresenta os dados de forma organizada. Também pode modificar o código para extrair uma tabela de outro site. Tenha em mente que nem todos os sites na Internet são tão fáceis de extrair dados. Muitos deles implementaram medidas de proteção de alto nível destinadas a impedir a extração, como CAPTCHA e bloqueio de endereços IP, mas, felizmente, existem serviços de terceiros, como o WebScrapingAPI, que oferecem rotação de IP e contorno de CAPTCHA, permitindo-lhe extrair esses alvos.
Aprofundando
Embora a técnica que descrevemos até agora seja suficiente para tabelas HTML simples, existem várias formas de a melhorar.
Uma potencial dificuldade é que a estrutura da tabela HTML pode não ser consistente em todas as páginas web. Por exemplo, a tabela pode ter um número diferente de colunas ou os dados podem estar aninhados em diferentes elementos HTML. Para lidar com estes casos, pode utilizar técnicas mais avançadas, como seletores CSS ou expressões XPath, para localizar os dados que pretende extrair.
Outro problema é que as páginas web utilizam frequentemente AJAX ou outras tecnologias do lado do cliente para carregar dados adicionais na página depois de esta ter sido carregada no navegador. Isto significa que a tabela HTML que está a extrair pode não conter todos os dados de que necessita. Para extrair este tipo de páginas, poderá ser necessário utilizar uma ferramenta como um navegador headless, que pode executar JavaScript e renderizar a página tal como um navegador web normal. Uma boa alternativa a isso é utilizar o nosso scraper, que pode devolver os dados após o JavaScript ser renderizado na página. Pode saber mais sobre isto consultando a nossa documentação.
Por fim, é importante considerar o desempenho e a escalabilidade do seu scraper. Se estiver a extrair tabelas grandes ou várias páginas, poderá ser necessário utilizar técnicas como a concorrência ou a limitação de taxa para garantir que o seu scraper consegue lidar com a carga.
Resumo
Espero que tenha considerado este recurso um bom ponto de partida para extrair tabelas HTML com Golang. Percorremos o processo de extração de dados de uma tabela HTML utilizando a linguagem de programação Go. Analisámos como recuperar o conteúdo HTML de uma página web, imprimi-lo no ecrã e apresentá-lo num formato tabular legível a olho nu. Também discutimos alguns dos desafios que poderá encontrar ao extrair tabelas HTML, incluindo estruturas de tabelas inconsistentes, carregamento de dados do lado do cliente e questões de desempenho e escalabilidade.
Embora seja possível criar o seu próprio scraper utilizando as técnicas descritas neste artigo, é frequentemente mais eficiente e fiável utilizar um serviço profissional de scraping. Estes serviços dispõem da infraestrutura, dos conhecimentos especializados e das medidas de segurança necessárias para lidar com grandes volumes de dados e tarefas complexas de scraping, e podem frequentemente fornecer dados num formato mais estruturado e prático, como CSV ou JSON.
Em resumo, a extração de tabelas HTML pode ser uma forma útil de extrair dados da Web, mas é importante ponderar cuidadosamente as vantagens e desvantagens entre criar o seu próprio scraper e utilizar um serviço profissional.




