Volver al blog
Guías
Andrei OgiolanLast updated on Mar 31, 20267 min read

Descubre cómo extraer datos de tablas HTML con Golang

Descubre cómo extraer datos de tablas HTML con Golang

Introducción

El web scraping es una técnica para extraer datos de sitios web y puede ser una herramienta muy útil para recopilar información de Internet. En este artículo veremos cómo extraer datos de tablas HTML con Golang, un lenguaje de programación muy popular conocido por su simplicidad, su compatibilidad con la concurrencia y su sólida biblioteca estándar.

¿Qué son las tablas HTML?

Las tablas HTML son un tipo de elemento en HTML (Hypertext Markup Language) que se utiliza para representar datos tabulares en una página web. Una tabla HTML consta de filas y columnas de celdas que contienen texto, imágenes u otros elementos HTML. Las tablas HTML se crean utilizando el elemento table y se estructuran mediante «<tr>» (fila de la tabla), «<td>» (celda de tabla), «<th>» (encabezado de tabla), «<caption>», «<col>», «<colgroup>», «<tbody>» (cuerpo de tabla), «<thead>» (cabecera de tabla) y «<tfoot>» (pie de tabla). Ahora repasemos cada uno de ellos y entremos en más detalle:

  • Elemento table: Define el inicio y el final de una tabla HTML.
  • Elemento tr (fila de tabla): Define una fila en una tabla HTML.
  • Elemento td (celda de tabla): Define una celda en una tabla HTML.
  • Elemento th (encabezado de tabla): Define una celda de encabezado en una tabla HTML. Las celdas de encabezado se muestran en negrita y centradas por defecto, y se utilizan para etiquetar las filas o columnas de la tabla.
  • Elemento caption: Define un título o leyenda para una tabla HTML. La leyenda suele mostrarse encima o debajo de la tabla.
  • Elementos col y colgroup: definen las propiedades de las columnas de una tabla HTML, como el ancho o la alineación.
  • Elementos tbody, thead y tfoot: definen las secciones del cuerpo, la cabecera y el pie de una tabla HTML, respectivamente. Estos elementos se pueden utilizar para agrupar filas y aplicar estilos o atributos a una sección específica de la tabla.

Para comprender mejor este concepto, veamos cómo es una tabla HTML:

A primera vista, parece una tabla normal y no podemos ver la estructura con los elementos descritos anteriormente. Esto no significa que no estén presentes, sino que el navegador ya los ha analizado por nosotros. Para poder ver la estructura HTML, hay que ir un paso más allá y utilizar las herramientas de desarrollo. Puedes hacerlo haciendo clic con el botón derecho del ratón en la página, seleccionando «Inspeccionar», haciendo clic en la herramienta «Seleccionar elemento» y, a continuación, haciendo clic en el elemento (en este caso, la tabla) del que deseas ver la estructura HTML. Tras seguir estos pasos, deberías ver algo como esto:

Las tablas HTML se utilizan habitualmente para presentar datos en un formato estructurado y tabular, como para tabular resultados o mostrar el contenido de una base de datos. Se pueden encontrar en una amplia variedad de sitios web y son un elemento importante a tener en cuenta a la hora de extraer datos de la web.

Configuración

Antes de empezar a extraer datos, debemos configurar nuestro entorno de Golang e instalar las dependencias necesarias. Asegúrate de tener Golang instalado y configurado en tu sistema y, a continuación, crea un nuevo directorio de proyecto e inicializa un archivo `go.mod`:

$ mkdir scraping-project

$ cd scraping-project

$ go mod init <NAME-OF-YOUR-PROJECT>

$ touch main.go

A continuación, debemos instalar una biblioteca para realizar solicitudes HTTP y analizar HTML. Hay varias opciones disponibles, pero para este artículo utilizaremos el paquete `net/http` de la biblioteca estándar y el paquete golang.org/x/net/html para analizar HTML. Estos paquetes se pueden instalar ejecutando el siguiente comando:

$ go get -u net/http golang.org/x/net/html

Ahora que nuestro entorno está configurado, estamos listos para empezar a crear nuestro rastreador de tablas HTML utilizando Golang.

Empecemos a extraer datos

Ahora que tenemos nuestro entorno configurado, podemos empezar a crear un scraper para extraer datos de una tabla HTML. El primer paso es enviar una solicitud HTTP a la página web que contiene la tabla HTML que queremos extraer. Podemos usar la función `http.Get` del paquete `net/http` para enviar una solicitud GET y recuperar el contenido 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)

}

A continuación, podemos utilizar la función `goquery.NewDocumentFromReader` del paquete goquery para analizar el contenido HTML y extraer los datos que necesitamos. Al igual que con cualquier otro paquete de Golang, primero hay que instalarlo de la siguiente manera:

$ go get github.com/PuerkitoBio/goquery

Y luego añadir el siguiente código, que analizará el HTML de la página:

doc, err := goquery.NewDocumentFromReader(resp.Body)

if err != nil {

    log.Fatal(err)

}

Ahora que tenemos un analizador y un extractor de elementos para nuestro HTML, podemos aprovechar la funcionalidad `doc.Find()` del paquete Goquery, que nos permite encontrar los elementos específicos que buscamos, en este caso, una tabla. Podemos utilizarla de la siguiente manera:

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()

            }

        })

    }

})

Eso es todo, ahora puedes extraer la tabla usando Golang y deberías poder verla en la pantalla así:

Como habrás notado, la estructura puede resultar bastante confusa y difícil de leer. La buena noticia es que puedes hacerlo mejor y mostrar los datos de forma clara en un formato tabular fácil de leer. Esta es una tarea perfecta para el paquete tablewriter, que puedes instalar de la siguiente manera:

$ go get github.com/olekukonko/tablewriter

Ahora tenemos que hacer algunos ajustes en nuestro código antes de pasar la información a tablewriter, como definir los encabezados de la tabla, las estructuras y almacenarlas en una matriz. Debería quedar algo así:

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()

}

Ahora deberías poder ver los datos mostrados en este formato:

En este punto, has conseguido crear un scraper en Golang que extrae una página web, y almacena y muestra los datos de forma clara. También puedes modificar el código para extraer una tabla de otra página web. Ten en cuenta que no todos los sitios web de Internet permiten extraer datos con tanta facilidad. Muchos de ellos han implementado medidas de protección de alto nivel diseñadas para impedir el scraping, como CAPTCHA y el bloqueo de direcciones IP, pero, afortunadamente, existen servicios de terceros, como WebScrapingAPI, que ofrecen rotación de IP y eludir CAPTCHA, lo que te permite extraer datos de esos objetivos.

Profundizando

Aunque la técnica que hemos descrito hasta ahora es suficiente para tablas HTML sencillas, hay varias formas de mejorarla.

Un posible problema es que la estructura de la tabla HTML puede no ser consistente en todas las páginas web. Por ejemplo, la tabla puede tener un número diferente de columnas o los datos pueden estar anidados en diferentes elementos HTML. Para gestionar estos casos, puedes utilizar técnicas más avanzadas, como selectores CSS o expresiones XPath, para localizar los datos que deseas extraer.

Otro problema es que las páginas web suelen utilizar AJAX u otras tecnologías del lado del cliente para cargar datos adicionales en la página una vez que esta se ha cargado en el navegador. Esto significa que la tabla HTML que estás rastreando puede no contener todos los datos que necesitas. Para extraer este tipo de páginas, es posible que tengas que utilizar una herramienta como un navegador sin interfaz gráfica, que puede ejecutar JavaScript y renderizar la página igual que un navegador web normal. Una buena alternativa a esto es utilizar nuestro extractor, que puede devolver los datos después de que se haya renderizado el JavaScript en la página. Puedes obtener más información al respecto consultando nuestra documentación.

Por último, es importante tener en cuenta el rendimiento y la escalabilidad de su scraper. Si está extrayendo datos de tablas grandes o de varias páginas, es posible que tenga que utilizar técnicas como la concurrencia o la limitación de velocidad para garantizar que su scraper pueda gestionar la carga.

Resumen

Espero que este recurso te haya servido como un buen punto de partida para extraer tablas HTML con Golang. Hemos recorrido el proceso de extracción de datos de una tabla HTML utilizando el lenguaje de programación Go. Hemos visto cómo recuperar el contenido HTML de una página web, imprimirlo en pantalla y mostrarlo en un formato tabular legible para el ojo humano. También hemos abordado algunos de los retos a los que puede enfrentarse al extraer datos de tablas HTML, incluyendo estructuras de tabla inconsistentes, la carga de datos del lado del cliente y problemas de rendimiento y escalabilidad.

Aunque es posible crear tu propio rastreador utilizando las técnicas descritas en este artículo, a menudo resulta más eficiente y fiable utilizar un servicio de rastreo profesional. Estos servicios cuentan con la infraestructura, la experiencia y las medidas de seguridad necesarias para gestionar grandes volúmenes de datos y tareas de rastreo complejas, y a menudo pueden proporcionar los datos en un formato más estructurado y práctico, como CSV o JSON.

En resumen, el scraping de tablas HTML puede ser una forma útil de extraer datos de la web, pero es importante sopesar cuidadosamente las ventajas y desventajas entre crear tu propio scraper y utilizar un servicio profesional.

Acerca del autor
Andrei Ogiolan, Desarrollador Full Stack @ WebScrapingAPI
Andrei OgiolanDesarrollador Full Stack

Andrei Ogiolan es desarrollador full stack en WebScrapingAPI, donde colabora en todas las áreas del producto y ayuda a crear herramientas y funciones fiables para la plataforma.

Empieza a crear

¿Estás listo para ampliar tu recopilación de datos?

Únete a más de 2000 empresas que utilizan WebScrapingAPI para extraer datos de la web a escala empresarial sin ningún gasto de infraestructura.