La Guía Definitiva Sobre Cómo Empezar Web Scraping Con Go
Sorin-Gabriel Marica el 14 oct 2022
Web scraping con Go es una gran manera de crear un raspador rápido y potente. Esto se debe a que GoLang es uno de los mejores lenguajes de programación que puedes utilizar para la concurrencia. Pero antes de saltar directamente a ello, primero debo contarte más sobre qué es el web scraping, y cómo puede ayudarte.
El web scraping es el proceso de extracción de datos de sitios web. Este proceso se puede hacer manualmente, pero este enfoque no es recomendable cuando se trata de una gran cantidad de datos. En este artículo exploraremos cómo puedes construir tu propio raspador web automatizado desde cero con Go.
Si eres nuevo en esto, puede que te preguntes cuáles son algunos de los casos de uso que tiene el Web Scraping. Aquí tienes una pequeña lista con algunos de los más comunes:
- Herramientas de comparación de precios - Puede crear muchas herramientas utilizando un raspador web. Una de las más comunes y útiles es una herramienta de comparación de precios. Una herramienta de este tipo extraería los precios de un producto de muchas fuentes y mostraría la mejor oferta posible.
- Aprendizaje automático - Si desea crear un modelo utilizando el aprendizaje automático, necesitará un conjunto de datos de entrenamiento. Aunque a veces puede encontrar conjuntos de datos existentes que puede utilizar, a menudo tendrá que hacer algo de trabajo extra y obtener los datos que necesita usted mismo.
- Investigación de mercado - Un tercer caso de uso es el de obtener información de Internet para averiguar quiénes son tus competidores y qué están haciendo. De esta forma, puedes mantenerte al día o adelantarte a la competencia, estando al tanto de cualquier novedad que puedan haber añadido.
¿Qué se necesita para el scraping de datos con go?
Antes de empezar necesitarás poder ejecutar código GoLang en tu máquina. Para ello todo lo que necesitas es instalar Go, si aún no lo has hecho. Puedes encontrar más detalles sobre cómo instalar Go, y cómo comprobar si lo tienes instalado aquí.
Lo otro que necesitarás es un IDE o un editor de texto de tu elección donde escribiremos el código. Yo prefiero usar Visual Studio Code, pero siéntete libre de usar lo que creas conveniente.
Y ya está. Bastante simple, ¿no? Ahora vamos a sumergirnos en el tema principal de este artículo, web scraping con go.
Crear un raspador web con Go
Para construir nuestro scraper primero necesitaremos un propósito, un conjunto de datos, que queremos recoger de una fuente específica. Así, como tema para nuestro scraper elegí raspar las descargas semanales de los primeros paquetes de npmjs.com que utilizan la palabra clave "framework". Puedes encontrarlos en esta página: https://www.npmjs.com/search?q=keywords:framework&page=0&ranking=optimal)
Inspeccione el contenido de la página que desea raspar
Para hacer un buen scraping, antes de empezar a extraer los datos, tendrás que ver dónde están. Con esto quiero decir que tendrás que construir los selectores HTML para consultar los datos, basándote en la estructura HTML de la página.
Para ver la estructura HTML de la página, puedes utilizar las herramientas para desarrolladores disponibles en la mayoría de los navegadores modernos. En Chrome, puede hacerlo en la página haciendo clic con el botón derecho en el elemento que desea extraer y haciendo clic en "Inspeccionar página". Una vez hecho esto verás algo como esto:

Basándonos en el HTML que puedes ver a la derecha (la ventana de inspección), ahora podemos construir los selectores que utilizaremos. De esta página sólo necesitamos las URLs de cada uno de los paquetes.
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 }}"):

Al pasar el ratón por encima de cada uno de los elementos nodelist devueltos, podemos ver que son exactamente los que estábamos buscando, por lo que podemos utilizar este selector.
Raspado de una página con Go
¡Por fin empezamos a construir el scraper! Para ello, primero debes crear una carpeta donde pondremos todo nuestro código. A continuación, tienes que abrir una ventana de terminal, ya sea desde tu IDE o desde tu sistema operativo e ir a nuestra carpeta.
Para abrir un terminal en la carpeta, utilizando Visual Studio Code puede hacer clic en Terminal -> Nuevo Terminal (desde la barra superior).

Ahora que tenemos nuestro terminal abierto, es hora de inicializar el proyecto. Puedes hacerlo ejecutando el comando
go mod init webscrapingapi.com/my-go-scraper
Esto creará en tu carpeta un archivo llamado go.mod con el siguiente contenido:
módulo webscrapingapi.com/my-go-scraper
go 1.19
Para realizar la petición a la página y extraer los selectores del HTML, utilizaremos Colly, un paquete de GoLang(consulta la documentación de Colly para más información). Para instalar este paquete tienes que ejecutar
ir a github.com/gocolly/colly
Ahora que tenemos todo preparado, todo lo que necesitamos hacer es crear nuestro archivo main.go , y escribir algo de código. El código para extraer todos los enlaces de la primera página de frameworks npmjs, es el siguiente:
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()
}
Si esto parece difícil de leer al principio, no se preocupe, en los párrafos siguientes lo desglosaremos y explicaremos.
Cada archivo golang debe comenzar con el nombre del paquete y las importaciones que Go utilizará. En este caso los dos paquetes que utilizamos son "fmt" para imprimir los enlaces que raspamos, y "Colly" (para el raspado real).
En la siguiente parte, creamos la función scrape() que se encarga de scrapear los enlaces que necesitamos. Para ello la función visita la primera página, y espera a encontrar el selector que decidimos. Cuando aparece un elemento de ese selector, sigue adelante e imprime el atributo href de ese elemento.
La última parte es la función main que es la función que se llama cada vez que ejecutamos un script golang. Para ejecutar el código anterior ejecuta main.go desde tu terminal, y deberías obtener la siguiente salida:

Como puedes ver, el atributo href tiene rutas relativas a los enlaces, por lo que necesitaremos anteponerle la url de npmjs.
Utilizar la concurrencia de GoLang en aras de la eficiencia
Una de las características más interesantes de GoLang son las GoRoutines. GoRoutines son simples hilos ligeros gestionados por el tiempo de ejecución Go. Lo bueno de esto es que Go puede ayudarnos a scrapear muchas urls al mismo tiempo con una velocidad de vértigo.
Antes hemos extraído los enlaces de los 20 primeros paquetes bajo la palabra clave "framework" en npmjs.com. Ahora intentaremos extraer todos estos enlaces al mismo tiempo y extraer las descargas semanales de cada uno de ellos. Para ello utilizaremos GoRoutines y WaitGroups.
Aquí está el código final para extraer las descargas semanales utilizando las 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()
}
Ahora vamos a discutir lo que se ha añadido a nuestro código anterior. Primero notarás que tenemos un nuevo paquete importado llamado "sync". Esto nos ayudará a utilizar rutinas golang y esperar a que los hilos terminen, antes de detener la ejecución del programa.
La siguiente cosa añadida es la nueva función llamada "scrapeWeeklyDownloads". Esta función acepta dos parámetros: la url del enlace que vamos a scrapear y un puntero WaitGroup. Lo que hace esta función es visitar la url dada y extraer las descargas semanales (usando el selector main > div > div:last-child > div:not([class]) p).
Los últimos cambios que notarás fueron en la función scrape donde creamos un WaitGroup usando var wg sync.WaitGroup. Aquí, para cada enlace de la página de paquetes, usamos wg.Add(1) y luego creamos una GoRoutine que llama a la función scrapeWeeklyDownloads. Al final de la función, la instrucción wg.Wait() hace que el código espere hasta que todas las GoRoutines terminen de ejecutarse.
Para más información sobre WaitGroups por favor revisa este ejemplo de golang.
¿Por qué GoRoutines y WaitGroups?
Usando concurrencia en golang con GoRoutines y WaitGroups podemos crear un scraper muy rápido. Ejecutando el ejemplo de código anterior nos devolverá la página y las descargas semanales de cada paquete. Pero, debido a que estamos usando multihilos, el orden en el que se mostrará esta información es desconocido (ya que los hilos se ejecutan a diferentes velocidades).
Si estás ejecutando el código usando linux o windows subsystem linux (wsl), puedes usar time go run main.go para ver el tiempo de ejecución de todo el script. Para mí, el tiempo de ejecución es de alrededor de 5 a 6 segundos. Esto es muy rápido, teniendo en cuenta que estamos raspando 21 páginas (Primero la página con los paquetes y luego las páginas de cada uno de los paquetes).
Otros obstáculos
La mayoría de los scrapers suelen contar con hacer una simple petición HTTP a la página, para obtener el contenido que necesitan. Esta solución es buena, pero a veces los sitios web muestran su información mediante renderizado javascript. Esto significa que el sitio web le mostrará primero sólo una parte de su contenido, cargando el resto dinámicamente a través de javascript.
Para scrapear tales páginas necesitarás usar chromedriver y controlar un navegador chrome real. Si bien hay algunas opciones para hacer esto en Golang, usted tendrá que hacer un poco de investigación adicional para este tema.
Incluso con la renderización javascript cubierta, todavía hay algunos obstáculos adicionales cuando se raspa un sitio web. Algunos sitios web pueden utilizar detecciones antibot, bloqueos de IP o captchas para evitar que los bots raspen su contenido. Para seguir haciendo scraping de esos sitios web, puedes intentar utilizar algunos consejos y trucos para el scraping web, como hacer que tu scraper sea más lento y actúe de forma más humana.
Pero, si usted quiere mantener su raspador rápido y hacer frente a estos obstáculos de una manera fácil, puede utilizar WebScrapingAPI. WebScrapingAPI es una API diseñada para ayudarte con el scraping rotando tu IP y evitando detecciones antibot. De esta manera puedes seguir usando la velocidad relámpago que proporciona GoLang y raspar tus datos en poco tiempo.
Conclusión sobre Web Scraping con Go
Web Scraping es una forma agradable y rápida de extraer datos de Internet, y se puede utilizar para muchos casos de uso diferentes. Puedes elegir entre extraer datos para tu modelo de aprendizaje automático o crear una aplicación desde cero utilizando los datos que has raspado.
GoLang es una de las mejores soluciones cuando se trata de concurrencia. Usando GoLang y Colly puedes construir un scraper rápido que traerá tus datos en poco tiempo. Esto hace que el raspado web con Go sea muy fácil y eficiente una vez que te acostumbras a la sintaxis de Go.
Noticias y actualidad
Manténgase al día de las últimas guías y noticias sobre raspado web suscribiéndose a nuestro boletín.
We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Artículos relacionados

¿Son los selectores XPath mejores que los selectores CSS para el web scraping? Conozca los puntos fuertes y las limitaciones de cada método y tome la decisión correcta para su proyecto.


Aprenda a raspar tablas HTML con Golang para una potente extracción de datos. Explore la estructura de las tablas HTML y construya un raspador web utilizando la simplicidad, la concurrencia y la robusta biblioteca estándar de Golang.


Aprenda a utilizar proxies con node-fetch, un popular cliente HTTP JavaScript, para construir raspadores web. Comprenda cómo funcionan los proxies en el raspado web, integre proxies con node-fetch y cree un raspador web compatible con proxies.
