🥳Únase a la Comunidad Scrapeless y Solicite su prueba gratuita para acceder a nuestro potente kit de herramientas de Web Scraping.
Volver al blog

Rastreo web con Golang: Tutorial paso a paso 2025

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

23-Jan-2025

La mayoría de los proyectos grandes de web scraping en Go comienzan descubriendo y organizando URLs usando un rastreador web de Golang. Esta herramienta te permite navegar un dominio objetivo inicial (también conocido como "URL semilla") y visitar recursivamente enlaces en la página para descubrir más enlaces.

Esta guía te enseñará cómo construir y optimizar un rastreador web de Golang usando ejemplos del mundo real. Y, antes de sumergirnos, también obtendrás información complementaria útil.

¡Sin más preámbulos, veamos qué cosas divertidas tenemos para ti hoy!

¿Qué es el rastreo web?

El rastreo web, en esencia, implica navegar sistemáticamente por sitios web para extraer datos útiles. Un rastreador web (a menudo llamado araña) recupera páginas web, analiza su contenido y procesa la información para cumplir objetivos específicos, como la indexación o la agregación de datos. Desglosémoslo:

Los rastreadores web envían solicitudes HTTP para recuperar páginas web de los servidores y procesar las respuestas. Piénsalo como un apretón de manos educado entre tu rastreador y el sitio web: "Hola, ¿puedo usar tus datos?".

Una vez que se recupera la página, el rastreador extrae los datos relevantes analizando el HTML. Las estructuras DOM ayudan a dividir la página en fragmentos manejables, y los selectores CSS actúan como un par de pinzas precisas, extrayendo los elementos que necesitas.

La mayoría de los sitios web distribuyen sus datos en varias páginas. Los rastreadores necesitan navegar este laberinto de paginación, todo mientras respetan los límites de velocidad para evitar parecer un bot hambriento de datos con esteroides.

Por qué Golang es perfecto para el rastreo web en 2025

Si el rastreo web fuera una carrera, Golang sería el auto deportivo que querrías en tu garaje. Sus características únicas lo convierten en el lenguaje ideal para los rastreadores web modernos.

  • Concurrencia: Las goroutines de Golang te permiten realizar múltiples solicitudes simultáneamente, extrayendo datos más rápido de lo que puedes decir "procesamiento paralelo".
  • Simplicidad: La sintaxis limpia y el diseño minimalista del lenguaje mantienen tu base de código manejable, incluso cuando se abordan proyectos de rastreo complejos.
  • Rendimiento: Golang se compila, lo que significa que se ejecuta a una velocidad increíble: ideal para manejar tareas de rastreo web a gran escala sin sudar.
  • Biblioteca estándar robusta: Con soporte integrado para solicitudes HTTP, análisis JSON y más, la biblioteca estándar de Golang te proporciona todo lo que necesitas para construir un rastreador desde cero.

¿Por qué luchar con herramientas torpes cuando puedes volar a través de los datos como un Gopher con cafeína? Golang combina velocidad, simplicidad y potencia, lo que lo convierte en la mejor opción para rastrear la web de manera eficiente y efectiva.

La legalidad del rastreo web no es una situación única para todos. Depende de cómo, dónde y por qué estás rastreando. Si bien la extracción de datos públicos generalmente es permisible, violar los términos de servicio o eludir las medidas anti-raspado puede provocar problemas legales.

Para mantenerte del lado correcto de la ley, aquí hay algunas reglas de oro:

  • Respeta las directivas robots.txt.
  • Evita raspar información sensible o restringida.
  • Solicita permiso si no estás seguro sobre la política de un sitio web.

¿Cómo construir tu primer rastreador web de Golang?

Requisitos previos

  • Asegúrate de tener instalada la última versión de Go. Puedes descargar el paquete de instalación del sitio web oficial de Golang y seguir las instrucciones para instalarlo.
  • Elige tu IDE preferido. Este tutorial utiliza Goland como editor.
  • Elige una biblioteca de web scraping de Go con la que te sientas cómodo. En este ejemplo, usaremos chromedp.

Para verificar tu instalación de Go, ingresa el siguiente comando en la terminal:

PowerShell Copy
go version

Si la instalación es exitosa, verás el siguiente resultado:

PowerShell Copy
go version go1.23.4 windows/amd64

Crea tu directorio de trabajo y, una vez dentro, ingresa los siguientes comandos:

  1. Inicializa el go mod:
PowerShell Copy
go mod init crawl
  1. Instala la dependencia chromedp:
PowerShell Copy
go get github.com/chromedp/chromedp
  1. Crea el archivo crawl.go.

Ahora podemos comenzar a escribir tu código de web scraper.

Obtener elementos de la página

Visita Lazada y usa las herramientas de desarrollador del navegador (F12) para identificar fácilmente los elementos y selectores de la página que necesitas.

  1. Obtén el campo de entrada y el botón de búsqueda junto a él:

Obtener elementos de la página
Obtener elementos de la página

Go Copy
func searchProduct(keyword string) chromedp.Tasks {
  return chromedp.Tasks{
   // espera a que el elemento de entrada sea visible
   chromedp.WaitVisible(`input[type=search]`, chromedp.ByQuery),
   // Ingresa el producto buscado.
   chromedp.SendKeys("input[type=search]", keyword, chromedp.ByQuery),
   // Haz clic en buscar
   chromedp.Click(".search-box__button--1oH7", chromedp.ByQuery),
  }
}
  1. Obtén los elementos de precio, título e imagen de la lista de productos:
  • Lista de productos
    Lista de productos

  • Elemento de imagen
    Elemento de imagen

  • Elemento de título
    Elemento de título

  • Elemento de precio
    Elemento de precio

Go Copy
func getNodes(nodes *[]*cdp.Node) chromedp.Tasks {
  return chromedp.Tasks{
   chromedp.WaitReady(`div[data-spm=list] .Bm3ON`, chromedp.ByQuery),
   scrollToBottom(), // Desplázate hasta el final para asegurarte de que todos los elementos de la página se representen.
   chromedp.Nodes("div[data-spm=list] .Bm3ON", nodes, chromedp.ByQueryAll),
  }
}

func scrollToBottom() chromedp.Action {
  return chromedp.ActionFunc(func(ctx context.Context) error {
   for i := 0; i < 4; i++ { // Desplázate repetidamente para asegurarte de que todas las imágenes se carguen.
    _ = chromedp.Evaluate("window.scrollBy(0, window.innerHeight);", nil).Do(ctx)
    time.Sleep(1 * time.Second)
   }
   return nil
  })
}

func getProductData(ctx context.Context, node *cdp.Node) (*Product, error) {
  product := new(Product)
  err := chromedp.Run(ctx,
   chromedp.WaitVisible(".Bm3ON img[type=product]", chromedp.ByQuery, chromedp.FromNode(node)),
   chromedp.AttributeValue(".Bm3ON img[type=product]", "src", &product.Img, nil, chromedp.ByQuery, chromedp.FromNode(node)),
   chromedp.AttributeValue(".Bm3ON .RfADt a", "title", &product.Title, nil, chromedp.ByQuery, chromedp.FromNode(node)),
   chromedp.TextContent(".Bm3ON .aBrP0 span", &product.Price, chromedp.ByQuery, chromedp.FromNode(node)),
  )
  if err != nil {
   return nil, err
  }
  return product, nil
}

Configurar el entorno de Chrome

Para una depuración más fácil, podemos iniciar un navegador Chrome en PowerShell y especificar un puerto de depuración remoto.

PowerShell Copy
chrome.exe --remote-debugging-port=9223

Podemos acceder a http://localhost:9223/json/list para recuperar la dirección de depuración remota expuesta del navegador, webSocketDebuggerUrl.

PowerShell Copy
[
  {
    "description": "",
    "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9223/devtools/page/85CE4D807D11D30D5F22C1AA52461080",
    "id": "85CE4D807D11D30D5F22C1AA52461080",
    "title": "localhost:9223/json/list",
    "type": "page",
    "url": "http://localhost:9223/json/list",
    "webSocketDebuggerUrl": "ws://localhost:9223/devtools/page/85CE4D807D11D30D5F22C1AA52461080"
  }
]

Ejecutar el código

El código completo es el siguiente:

Go Copy
package main

import (
  "context"
  "encoding/json"
  "flag"
  "log"
  "time"

  "github.com/chromedp/cdproto/cdp"
  "github.com/chromedp/chromedp"
)

type Product struct {
  ID    string `json:"id"`
  Img   string `json:"img"`
  Price string `json:"price"`
  Title string `json:"title"`
}

func main() {
  product := flag.String("product", "iphone15", "tu palabra clave del producto")
  url := flag.String("webSocketDebuggerUrl", "", "tu URL de websocket")

  flag.Parse()

  var baseCxt context.Context

  if *url != "" {
   baseCxt, _ = chromedp.NewRemoteAllocator(context.Background(), *url)
  } else {
   baseCxt = context.Background()
  }

  ctx, cancel := chromedp.NewContext(
   baseCxt,
  )

  defer cancel()
  var nodes []*cdp.Node

  err := chromedp.Run(ctx,
   chromedp.Navigate(`https://www.lazada.com.my/`),
   searchProduct(*product),
   getNodes(&nodes),
  )

  products := make([]*Product, 0, len(nodes))

  for _, v := range nodes {
   product, err := getProductData(ctx, v)
   if err != nil {
    log.Println("error al ejecutar la tarea del nodo: ", err)
    continue
   }
   products = append(products, product)
  }
  if err != nil {
   log.Fatal(err)
  }

  jsonData, _ := json.Marshal(products)

  log.Println(string(jsonData))
}

func searchProduct(keyword string) chromedp.Tasks {
  return chromedp.Tasks{
   // espera a que el elemento de entrada sea visible
   chromedp.WaitVisible(`input[type=search]`, chromedp.ByQuery),
   // Ingresa el producto buscado.
   chromedp.SendKeys("input[type=search]", keyword, chromedp.ByQuery),
   // Haz clic en buscar
   chromedp.Click(".search-box__button--1oH7", chromedp.ByQuery),
  }
}

func getNodes(nodes *[]*cdp.Node) chromedp.Tasks {
  return chromedp.Tasks{
   chromedp.WaitReady(`div[data-spm=list] .Bm3ON`, chromedp.ByQuery),
   scrollToBottom(), // Desplázate hasta el final para asegurarte de que todos los elementos de la página se representen.
   chromedp.Nodes("div[data-spm=list] .Bm3ON", nodes, chromedp.ByQueryAll),
  }
}

func scrollToBottom() chromedp.Action {
  return chromedp.ActionFunc(func(ctx context.Context) error {
   for i := 0; i < 4; i++ { // Desplázate repetidamente para asegurarte de que todas las imágenes se carguen.
    _ = chromedp.Evaluate("window.scrollBy(0, window.innerHeight);", nil).Do(ctx)
    time.Sleep(1 * time.Second)
   }
   return nil
  })
}

func getProductData(ctx context.Context, node *cdp.Node) (*Product, error) {
  product := new(Product)
  err := chromedp.Run(ctx,
   chromedp.WaitVisible(".Bm3ON img[type=product]", chromedp.ByQuery, chromedp.FromNode(node)),
   chromedp.AttributeValue(".Bm3ON img[type=product]", "src", &product.Img, nil, chromedp.ByQuery, chromedp.FromNode(node)),
   chromedp.AttributeValue(".Bm3ON .RfADt a", "title", &product.Title, nil, chromedp.ByQuery, chromedp.FromNode(node)),
   chromedp.TextContent(".Bm3ON .aBrP0 span", &product.Price, chromedp.ByQuery, chromedp.FromNode(node)),
  )
  if err != nil {
   return nil, err
  }
  product.ID = node.AttributeValue("data-item-id")
  return product, nil
}

Al ejecutar el siguiente comando, recuperarás los resultados de los datos extraídos:

PowerShell Copy
go run .\crawl.go -product="TU PALABRA CLAVE" -webSocketDebuggerUrl="TU WEBSOCKETDEBUGGERURL"
JSON Copy
[
    {
        "id": "3792910846",
        "img": "https://img.lazcdn.com/g/p/a79df6b286a0887038c16b7600e38f4f.png_200x200q75.png_.webp",
        "price": "RM3,809.00",
        "title": "Apple iPhone 15"
    },
    {
        "id": "3796593281",
        "img": "https://img.lazcdn.com/g/p/627828b5fa28d708c5b093028cd06069.png_200x200q75.png_.webp",
        "price": "RM3,319.00",
        "title": "Apple iPhone 15"
    },
    {
        "id": "3794514070",
        "img": "https: //img.lazcdn.com/g/p/6f4ddc2693974398666ec731a713bcfd.jpg_200x200q75.jpg_.webp",
        "price": "RM3,499.00",
        "title": "Apple iPhone 15"
    },
    {
        "id": "3796440931",
        "img": "https://img.lazcdn.com/g/p/8df101af902d426f3e3a9748bafa7513.jpg_200x200q75.jpg_.webp",
        "price": "RM4,399.00",
        "title": "Apple iPhone 15"
    },
    
    ......
    
    {
        "id": "3793164816",
        "img": "https://img.lazcdn.com/g/p/b6c3498f75f1215f24712a25799b0d19.png_200x200q75.png_.webp",
        "price": "RM3,799.00",
        "title": "Apple iPhone 15"
    },
    {
        "id": "3793322260",
        "img": "https: //img.lazcdn.com/g/p/67199db1bd904c3b9b7ea0ce32bc6ace.png_200x200q75.png_.webp",
        "price": "RM5,644.00",
        "title": "[Ready Stock] Apple iPhone 15 Pro"
    },
    {
        "id": "3796624559",
        "img": "https://img.lazcdn.com/g/p/81a814a9c829afa200fbc691c9a0c30c.png_200x200q75.png_.webp",
        "price": "RM6,679.00",
        "title": "Apple iPhone 15 Pro (1TB)"
    }
]

Técnicas avanzadas para escalar tu rastreador web

¡Tu rastreador web necesita mejoras! Para recopilar datos de manera efectiva sin ser bloqueado o sobrecargado, debes implementar técnicas que equilibren la velocidad, la confiabilidad y la optimización de recursos.

Exploremos algunas estrategias avanzadas para asegurarte de que tu rastreador sobresalga bajo cargas de trabajo pesadas.

Mantén tu solicitud y sesión

Al rastrear la web, bombardear un servidor con demasiadas solicitudes en poco tiempo es una forma segura de ser detectado y prohibido. Los sitios web a menudo monitorean la frecuencia de las solicitudes del mismo cliente, y un aumento repentino puede activar mecanismos anti-bot.

Go Copy
package main

import (
        "fmt"
        "io/ioutil"
        "net/http"
        "time"
)

func main() {
        // Crea un cliente HTTP reutilizable
        client := &http.Client{}

        // URLs para rastrear
        urls := []string{
                "https://example.com/page1",
                "https://example.com/page2",
                "https://example.com/page3",
        }

        // Intervalo entre solicitudes (por ejemplo, 2 segundos)
        requestInterval := 2 * time.Second

        for _, url := range urls {
                // Crea una nueva solicitud HTTP
                req, _ := http.NewRequest("GET", url, nil)
                req.Header.Set("User-Agent", "Mozilla/5.0 (compatible; WebCrawler/1.0)")

                // Envía la solicitud
                resp, err := client.Do(req)
                if err != nil {
                        fmt.Println("Error:", err)
                        continue
                }

                // Lee e imprime la respuesta
                body, _ := ioutil.ReadAll(resp.Body)
                fmt.Printf("Respuesta de %s:\n%s\n", url, body)
                resp.Body.Close()

                // Espera antes de enviar la siguiente solicitud
                time.Sleep(requestInterval)
        }
}

Evita enlaces duplicados

No hay nada peor que desperdiciar recursos rastreando la misma URL dos veces. Implementa un sistema de eliminación de duplicados robusto manteniendo un conjunto de URL (por ejemplo, un mapa hash o una base de datos Redis) para rastrear las páginas ya visitadas. Esto no solo ahorra ancho de banda, sino que también garantiza que tu rastreador funcione de manera eficiente y no se pierda páginas nuevas.

Gestión de proxies para evitar bloqueos de IP

El raspado a escala a menudo activa medidas anti-bot, lo que lleva a bloqueos de IP. Para evitar esto, integra la rotación de proxies en tu rastreador.

  • Usa grupos de proxies para distribuir las solicitudes entre varias IP.
  • Rota los proxies dinámicamente para que tus solicitudes parezcan originarse de diferentes usuarios y ubicaciones.

Prioriza páginas específicas

Priorizar páginas específicas ayuda a optimizar tu proceso de rastreo y te permite concentrarte en rastrear enlaces utilizables. En el rastreador actual, usamos selectores CSS para apuntar solo a enlaces de paginación y extraer información valiosa del producto.

Sin embargo, si estás interesado en todos los enlaces de una página y quieres priorizar la paginación, puedes mantener una cola separada y procesar los enlaces de paginación primero.

Go Copy
package main

import (
    "fmt"

    "github.com/gocolly/colly"
)

// ...

// crea variables para separar los enlaces de paginación de otros enlaces
var paginationURLs = []string{}
var otherURLs = []string{}

func main() {
    // ...
}

func crawl (currenturl string, maxdepth int) {
    // ...

    // ----- encuentra y visita todos los enlaces ---- //
    // selecciona el atributo href de todas las etiquetas de anclaje
    c.OnHTML("a[href]", func(e *colly.HTMLElement) {
        // obtén la URL absoluta
        link := e.Request.AbsoluteURL(e.Attr("href"))
        // verifica si la URL actual ya ha sido visitada
        if link != "" && !visitedurls[link] {
            // agrega la URL actual a visitedURLs
            visitedurls[link] = true
            if e.Attr("class") == "page-numbers" {
                paginationURLs = append(paginationURLs, link)
             } else {
                otherURLs = append(otherURLs, link)
             }
        }
    })


    // ...

    // procesa los enlaces de paginación primero
    for len(paginationURLs) > 0 {
        nextURL := paginationURLs[0]
        paginationURLs = paginationURLs[1:]
        visitedurls[nextURL] = true
        err := c.Visit(nextURL)
        if err != nil {
            fmt.Println("Error al visitar la página:", err)
        }
    }

    // procesa otros enlaces
    for len(otherURLs) > 0 {
        nextURL := otherURLs[0]
        otherURLs = otherURLs[1:]
        visitedurls[nextURL] = true
        err := c.Visit(nextURL)
        if err != nil {
            fmt.Println("Error al visitar la página:", err)
        }
    }

}

API de raspado Scrapeless: Herramienta de rastreo efectiva

¿Por qué la API de raspado Scrapeless es más ideal?

La API de raspado Scrapeless está diseñada para simplificar el proceso de extracción de datos de sitios web y puede navegar por los entornos web más complejos, gestionando eficazmente el contenido dinámico y la representación de JavaScript.

Además, la API de raspado Scrapeless aprovecha una red global que abarca 195 países, con acceso a más de 70 millones de IP residenciales. Con un tiempo de actividad del 99,9% y tasas de éxito excepcionales, Scrapeless supera fácilmente desafíos como los bloqueos de IP y CAPTCHA, lo que lo convierte en una solución robusta para la automatización web compleja y la recopilación de datos impulsada por IA.

Con nuestra API de raspado avanzada, puedes acceder a los datos que necesitas sin tener que escribir o mantener scripts de raspado complejos.

Ventajas de la API de raspado

Scrapeless admite la representación de JavaScript de alto rendimiento, lo que le permite manejar contenido dinámico (como datos cargados a través de AJAX o JavaScript) y raspar sitios web modernos que dependen de JS para la entrega de contenido.

  • Precios asequibles: Scrapeless está diseñado para ofrecer un valor excepcional.
  • Estabilidad y confiabilidad: Con un historial comprobado, Scrapeless proporciona respuestas de API estables, incluso bajo cargas de trabajo altas.
  • Altas tasas de éxito: Despídete de las extracciones fallidas y Scrapeless promete un 99,99% de acceso exitoso a los datos de Google SERP.
  • Escalabilidad: Maneja miles de consultas sin esfuerzo, gracias a la robusta infraestructura detrás de Scrapeless.

¡Obtén la API de raspado Scrapeless económica y potente ahora!

Scrapeless ofrece una plataforma de raspado web confiable y escalable a precios competitivos, asegurando un excelente valor para sus usuarios:

  • Navegador de raspado: Desde $0.09 por hora
  • API de raspado: Desde $1.00 por 1000 URLs
  • Desbloqueador web: $0.20 por 1000 URLs
  • Resolutor de CAPTCHA: Desde $0.80 por 1000 URLs
  • Proxies: $2.80 por GB

Al suscribirte, puedes disfrutar de descuentos de hasta un 20% de descuento en cada servicio. ¿Tienes requisitos específicos? ¡Contáctanos hoy a business@scrapeless.com y te ofreceremos ahorros aún mayores adaptados a tus necesidades!

¿Cómo usar la API de raspado Scrapeless?

Es muy fácil usar la API de raspado Scrapeless para rastrear datos de Lazada. Solo necesitas una solicitud simple para obtener todos los datos que deseas. ¿Cómo llamar a la API de Scrapeless rápidamente? Sigue mis pasos:

  • Paso 1. Inicia sesión en Scrapeless
  • Paso 2. Haz clic en "API de raspado"
API de raspado
  • Paso 3. Encuentra nuestra API de "Lazada" e introdúcela:
Lazada
  • Paso 4. Completa la información del producto que deseas rastrear en el cuadro de operaciones de la izquierda. Cuando usas chromedp para rastrear datos, ya has obtenido el ID del producto rastreado. Ahora solo necesitas agregar el ID al parámetro itemId para obtener datos más detallados sobre el producto. Luego selecciona el lenguaje de expresión que deseas:
Completa la información
  • Paso 5. Haz clic en "Iniciar raspado" y los resultados del rastreo del producto aparecerán en el cuadro de vista previa de la derecha:
Iniciar raspado

Puedes consultar nuestro código de ejemplo de Golang o visitar nuestra documentación de la API para otros lenguajes.

Go Copy
package main

import (
  "bytes"
  "encoding/json"
  "fmt"
  "io/ioutil"
  "net/http"
)

type Payload struct {
  Actor string         `json:"actor"`
  Input map[string]any `json:"input"`
  Proxy map[string]any `json:"proxy"`
}

func sendRequest() error {
  host := "api.scrapeless.com"
  url := fmt.Sprintf("https://%s/api/v1/scraper/request", host)
  token := "TU_TOKEN"

  headers := map[string]string{"x-api-token": token}

  inputData := map[string]any{
   "itemId": "3792910846", // Reemplaza con el itemId que deseas obtener.
   "site":   "my",
  }

  proxy := map[string]any{
   "country": "ANY",
  }

  payload := Payload{
   Actor: "scraper.lazada",
   Input: inputData,
   Proxy: proxy,
  }

  jsonPayload, err := json.Marshal(payload)
  if err != nil {
   return err
  }

  req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonPayload))
  if err != nil {
   return err
  }

  for key, value := range headers {
   req.Header.Set(key, value)
  }

  client := &http.Client{}
  resp, err := client.Do(req)
  if err != nil {
   return err
  }
  defer resp.Body.Close()

  body, err := ioutil.ReadAll(resp.Body)
  if err != nil {
   return err
  }
  fmt.Printf("body %s\n", string(body))

  return nil
}

func main() {
  err := sendRequest()
  if err != nil {
   fmt.Println("Error:", err)
   return
  }
}

Después de ejecutar, obtendrás los siguientes datos detallados. Incluidos enlaces, imágenes, SKU, reseñas, mismo vendedor, etc.

Debido a limitaciones de espacio, solo mostramos una porción de los resultados del rastreo aquí. ¡Puedes visitar nuestro Panel de Control y obtener una prueba gratuita para rastrear rápidamente y obtener los resultados completos del rastreo!

JSON Copy
{
    "Breadcrumb": [
        {
            "title": "Móviles y Tabletas",
            "url": "https://www.lazada.com.my/shop-mobiles-tablets/"
        },
        {
            "title": "Smartphones",
            "url": "https://www.lazada.com.my/shop-mobiles/"
        },
        {
            "title": "Apple iPhone 15"
        }
    ],
    "deliveryOptions": {
        "21911329880": [
            {
                "badge": false,
                "dataType": "delivery",
                "deliveryWorkTimeMax": "2025-01-27T23:27+08:00[GMT+08:00]",
                "deliveryWorkTimeMin": "2025-01-24T23:27+08:00[GMT+08:00]",
                "description": "Para artículos locales, puedes esperar recibir tu artículo dentro de 2-4 días hábiles. <br/>El costo de envío se determina por el tamaño/peso total de los productos comprados al vendedor.<br/><br/><a href=\"https://www.lazada.com.my/helpcenter/shipping_delivery/#answer-faq-whatisshippingfee-ans\" target=\"_blank\">Más información</a>",
                "duringTime": "Garantizado entre el 24 y 27 de enero",
                "fee": "RM4.90",
                "feeValue": 4.9,
                "hasTip": true,
                "title": "Envío estándar",
                "type": "standard"
            },
            {
                "badge": true,
                "dataType": "service",
                "description": "",
                "feeValue": 0,
                "hasTip": true,
                "title": "Pago contra reembolso no disponible",
                "type": "noCOD"
            }
        ],
        "21911329881": [
            {
                "badge": false,
                "dataType": "delivery",
                "deliveryWorkTimeMax": "2025-01-27T23:27+08:00[GMT+08:00]",
                "deliveryWorkTimeMin": "2025-01-24T23:27+08:00[GMT+08:00]",
                "description": "Para artículos locales, puedes esperar recibir tu artículo dentro de 2-4 días hábiles. <br/>El costo de envío se determina por el tamaño/peso total de los productos comprados al vendedor.<br/><br/><a href=\"https://www.lazada.com.my/helpcenter/shipping_delivery/#answer-faq-whatisshippingfee-ans\" target=\"_blank\">Más información</a>",
                "duringTime": "Garantizado entre el 24 y 27 de enero",
                "fee": "RM4.90",
                "feeValue": 4.9,
                "hasTip": true,
                "title": "Envío estándar",
                "type": "standard"
            },
            {
                "badge": true,
                "dataType": "service",
                "description": "",
                "feeValue": 0,
                "hasTip": true,
                "title": "Pago contra reembolso no disponible",
                "type": "noCOD"
            }
        ],
        ...

Lecturas adicionales

Mejores prácticas y consideraciones de rastreo de Golang

Rastreo paralelo y concurrencia

Raspar varias páginas de forma sincrónica puede provocar ineficiencias porque solo una goroutine puede manejar tareas activamente en un momento dado. Tu rastreador web pasa la mayor parte del tiempo esperando respuestas y procesando datos antes de pasar a la siguiente tarea.

Sin embargo, aprovechar las capacidades de concurrencia de Go para intentar el rastreo concurrente puede reducir significativamente tu tiempo de rastreo general.

Sin embargo, debes gestionar la concurrencia adecuadamente para evitar sobrecargar el servidor de destino y activar restricciones anti-bot.

Rastreo de páginas renderizadas con JavaScript en Go

Aunque Colly es una excelente herramienta de rastreo web con muchas funciones integradas, no puede rastrear páginas renderizadas con JavaScript (contenido dinámico). Solo puede recuperar y analizar HTML estático, y el contenido dinámico no existe en el HTML estático de un sitio web.

Sin embargo, puedes integrarte con un navegador sin cabeza o un motor JavaScript para rastrear contenido dinámico.

Pensamientos finales

Aprendiste a construir un rastreador web de Golang usando programación avanzada. Ten en cuenta que, si bien construir un raspador web para navegar por la web es un excelente punto de partida, debes superar las medidas anti-bot para acceder a sitios web modernos.

En lugar de luchar con una configuración manual que probablemente fallará, considera la API de raspado Scrapeless, la solución más confiable para evitar cualquier sistema anti-bot.

¡Prueba Scrapeless gratis hoy para empezar!

En Scrapeless, solo accedemos a datos disponibles públicamente y cumplimos estrictamente con las leyes, regulaciones y políticas de privacidad del sitio web aplicables. El contenido de este blog es sólo para fines de demostración y no implica ninguna actividad ilegal o infractora. No ofrecemos garantías y renunciamos a toda responsabilidad por el uso de la información de este blog o enlaces de terceros. Antes de realizar cualquier actividad de scraping, consulte a su asesor legal y revise los términos de servicio del sitio web de destino u obtenga los permisos necesarios.

Artículos más populares

Catalogar