Compartir tecnología

Marco de rastreo Go1.19: simplifique el rastreo automatizado de plantillas de sitios

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

introducción

Web Scraper es una herramienta que extrae automáticamente datos de sitios web. Se utilizan ampliamente en la recopilación de datos, la optimización de motores de búsqueda, la investigación de mercado y otros campos. Este artículo presentará en detalle cómo utilizar Go 1.19 para implementar una herramienta de rastreo de plantillas de sitio automatizada simplificada para ayudar a los desarrolladores a recopilar datos de manera eficiente.

Tabla de contenido

  1. Preparación ambiental
  2. Conceptos básicos de los rastreadores web.
  3. Ir a la selección del marco del rastreador
  4. Proceso básico de diseño de un rastreador.
  5. Implementar un rastreador web simple
  6. Analizar contenido HTML
  7. Procesamiento concurrente de rastreadores
  8. almacenamiento de datos
  9. Mecanismo de reintento y manejo de errores
  10. Caso práctico: rastreo de sitios web de noticias
  11. Funciones avanzadas y optimizaciones.
  12. en conclusión

1. Preparación del entorno

Antes de comenzar, asegúrese de tener Go 1.19 instalado en su sistema. Puede verificar la versión de Go con el siguiente comando:

go version
  • 1

Si aún no has instalado Go, puedes descargarlo desde Ir al sitio web oficial Descargue e instale la última versión.

2. Conceptos básicos de los rastreadores web.

El flujo de trabajo básico de un rastreador web es el siguiente:

  1. Enviar petición: envía una solicitud HTTP a la página web de destino.
  2. Obtener una respuesta: recibe la respuesta HTTP devuelta por el servidor.
  3. analizar el contenido: Extraiga los datos requeridos de la respuesta.
  4. Almacenamiento de datos: guarde los datos extraídos en un archivo o base de datos local.
  5. Manejar enlaces: extrae enlaces de páginas web y continúa rastreando otras páginas.

3. Vaya a la selección del marco del rastreador

En el lenguaje Go, existen varios marcos de rastreo populares, como:

  • Colly: un marco de rastreo rápido y elegante que proporciona una rica funcionalidad y un buen rendimiento.
  • Goquery: una biblioteca similar a jQuery para analizar y manipular documentos HTML.
  • Cliente HTTP: el paquete net/http de la biblioteca estándar puede satisfacer las necesidades de solicitudes HTTP más simples.

Este artículo utilizará principalmente Colly y Goquery para el rastreo web y el análisis de contenido.

4. Proceso básico de diseño de un rastreador.

Diseñaremos una herramienta de rastreo de plantillas de sitios automatizada simplificada. El proceso básico es el siguiente:

  1. Inicialice la configuración del rastreador.
  2. Envíe una solicitud HTTP para obtener el contenido de la página web.
  3. Utilice Goquery para analizar contenido HTML y extraer los datos necesarios.
  4. Guarde los datos en un archivo o base de datos local.
  5. Manejo de errores y mecanismos de reintento.
  6. Utilice procesamiento simultáneo para mejorar la eficiencia del rastreo.

5. Implemente un rastreador web sencillo

Primero, cree un nuevo proyecto Go:

mkdir go_scraper
cd go_scraper
go mod init go_scraper
  • 1
  • 2
  • 3

Luego, instala Colly y Goquery:

go get -u github.com/gocolly/colly
go get -u github.com/PuerkitoBio/goquery
  • 1
  • 2

A continuación, escriba un rastreador simple para rastrear contenido web:

package main

import (
    "fmt"
    "github.com/gocolly/colly"
)

func main() {
    // 创建一个新的爬虫实例
    c := colly.NewCollector()

    // 设置请求时的回调函数
    c.OnRequest(func(r *colly.Request) {
        fmt.Println("Visiting", r.URL.String())
    })

    // 设置响应时的回调函数
    c.OnResponse(func(r *colly.Response) {
        fmt.Println("Visited", r.Request.URL)
        fmt.Println("Response:", string(r.Body))
    })

    // 设置错误处理的回调函数
    c.OnError(func(r *colly.Response, err error) {
        fmt.Println("Error:", err)
    })

    // 设置HTML解析时的回调函数
    c.OnHTML("title", func(e *colly.HTMLElement) {
        fmt.Println("Title:", e.Text)
    })

    // 开始爬取
    c.Visit("http://example.com")
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

Al ejecutar el código anterior, se rastreará el contenido de http://example.com e imprimirá el título de la página.

6. Analizar contenido HTML

Para extraer los datos requeridos de la página web, necesitamos usar Goquery para analizar el contenido HTML. El siguiente ejemplo muestra cómo utilizar Goquery para extraer enlaces y texto de una página web:

package main

import (
    "fmt"
    "github.com/gocolly/colly"
    "github.com/PuerkitoBio/goquery"
)

func main() {
    c := colly.NewCollector()

    c.OnHTML("body", func(e *colly.HTMLElement) {
        e.DOM.Find("a").Each(func(index int, item *goquery.Selection) {
            link, _ := item.Attr("href")
            text := item.Text()
            fmt.Printf("Link #%d: %s (%s)n", index, text, link)
        })
    })

    c.Visit("http://example.com")
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

7. Procesamiento concurrente de rastreadores.

Para mejorar la eficiencia del rastreador, podemos utilizar la función de concurrencia de Colly:

package main

import (
    "fmt"
    "github.com/gocolly/colly"
    "github.com/PuerkitoBio/goquery"
    "log"
    "time"
)

func main() {
    c := colly.NewCollector(
        colly.Async(true), // 启用异步模式
    )

    c.Limit(&colly.LimitRule{
        DomainGlob:  "*",
        Parallelism: 2, // 设置并发数
        Delay:       2 * time.Second,
    })

    c.OnHTML("body", func(e *colly.HTMLElement) {
        e.DOM.Find("a").Each(func(index int, item *goquery.Selection) {
            link, _ := item.Attr("href")
            text := item.Text()
            fmt.Printf("Link #%d: %s (%s)n", index, text, link)
            c.Visit(e.Request.AbsoluteURL(link))
        })
    })

    c.OnRequest(func(r *colly.Request) {
        fmt.Println("Visiting", r.URL.String())
    })

    c.OnError(func(r *colly.Response, err error) {
        log.Println("Error:", err)
    })

    c.Visit("http://example.com")

    c.Wait() // 等待所有异步任务完成
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

8. Almacenamiento de datos

Guarde los datos capturados en un archivo o base de datos local. A continuación se muestra un archivo CSV como ejemplo:

package main

import (
    "encoding/csv"
    "fmt"
    "github.com/gocolly/colly"
    "github.com/PuerkitoBio/goquery"
    "log"
    "os"
    "time"
)

func main() {
    file, err := os.Create("data.csv")
    if err != nil {
        log.Fatalf("could not create file: %v", err)
    }
    defer file.Close()

    writer := csv.NewWriter(file)
    defer writer.Flush()

    c := colly.NewCollector(
        colly.Async(true),
    )

    c.Limit(&colly.LimitRule{
        DomainGlob:  "*",
        Parallelism: 2,
        Delay:       2 * time.Second,
    })

    c.OnHTML("body", func(e *colly.HTMLElement) {
        e.DOM.Find("a").Each(func(index int, item *goquery.Selection) {
            link, _ := item.Attr("href")
            text := item.Text()
            fmt.Printf("Link #%d: %s (%s)n", index, text, link)
            writer.Write([]string{text, link})
            c.Visit(e.Request.AbsoluteURL(link))
        })
    })

    c.OnRequest(func(r *colly.Request) {
        fmt.Println("Visiting", r.URL.String())
    })

    c.OnError(func(r *colly.Response, err error) {
        log.Println("Error:", err)
    })

    c.Visit("http://example.com")

    c.Wait()
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

9. Manejo de errores y mecanismo de reintento.

Para mejorar la estabilidad del rastreador, debemos manejar los errores de solicitud e implementar un mecanismo de reintento:

package main

import (
    "fmt"
    "github.com/gocolly/colly"
    "github.com/PuerkitoBio/goquery"
    "log"
    "os"
    "time"
)

func main() {
    file, err := os.Create("data.csv")
    if err != nil {
        log.Fatalf("could not create file: %v", err)
    }
    defer file.Close()

    writer := csv.NewWriter(file)
    defer writer.Flush()

    c := colly.NewCollector(
        colly.Async(true),
        colly.MaxDepth(1),
    )

    c.Limit(&colly.LimitRule{
        DomainGlob:  "*",
        Parallelism: 2,
        Delay:       2 * time.Second,
    })

    c.OnHTML("body", func(e *colly.HTMLElement) {
        e.DOM.Find("a").Each(func(index int, item *goquery.Selection) {
            link, _ := item.Attr("href")
            text := item.Text()
            fmt.Printf("Link #%d: %s (%s)

n", index, text, link)
            writer.Write([]string{text, link})
            c.Visit(e.Request.AbsoluteURL(link))
        })
    })

    c.OnRequest(func(r *colly.Request) {
        fmt.Println("Visiting", r.URL.String())
    })

    c.OnError(func(r *colly.Response, err error) {
        log.Println("Error:", err)
        // 重试机制
        if r.StatusCode == 0 || r.StatusCode >= 500 {
            r.Request.Retry()
        }
    })

    c.Visit("http://example.com")

    c.Wait()
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

10. Caso práctico: rastreo de sitios web de noticias

El siguiente ejemplo muestra cómo extraer los títulos y enlaces de un sitio web de noticias y guardarlos en un archivo CSV:

package main

import (
    "encoding/csv"
    "fmt"
    "github.com/gocolly/colly"
    "log"
    "os"
    "time"
)

func main() {
    file, err := os.Create("news.csv")
    if err != nil {
        log.Fatalf("could not create file: %v", err)
    }
    defer file.Close()

    writer := csv.NewWriter(file)
    defer writer.Flush()

    writer.Write([]string{"Title", "Link"})

    c := colly.NewCollector(
        colly.Async(true),
    )

    c.Limit(&colly.LimitRule{
        DomainGlob:  "*",
        Parallelism: 5,
        Delay:       1 * time.Second,
    })

    c.OnHTML(".news-title", func(e *colly.HTMLElement) {
        title := e.Text
        link := e.ChildAttr("a", "href")
        writer.Write([]string{title, e.Request.AbsoluteURL(link)})
        fmt.Printf("Title: %snLink: %sn", title, e.Request.AbsoluteURL(link))
    })

    c.OnRequest(func(r *colly.Request) {
        fmt.Println("Visiting", r.URL.String())
    })

    c.OnError(func(r *colly.Response, err error) {
        log.Println("Error:", err)
        if r.StatusCode == 0 || r.StatusCode >= 500 {
            r.Request.Retry()
        }
    })

    c.Visit("http://example-news-site.com")

    c.Wait()
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

11. Funciones avanzadas y optimizaciones.

Usa un proxy

Para evitar ser bloqueado por el sitio web de destino, puede utilizar un proxy:

c.SetProxy("http://proxyserver:port")
  • 1

Agente de usuario enmascarado

Finge ser un navegador diferente configurando el agente de usuario:

c.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
  • 1

Rastreador distribuido

Puede utilizar la biblioteca de extensiones de Colly, Colly-Redis, para implementar rastreadores distribuidos:

import (
    "github.com/gocolly/redisstorage"
)

func main() {
    c := colly.NewCollector()
    redisStorage := &redisstorage.Storage{
        Address:  "localhost:6379",
        Password: "",
        DB:       0,
        Prefix:   "colly",
    }
    c.SetStorage(redisStorage)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Raspado web dinámico

Para páginas web dinámicas, puedes utilizar un navegador sin cabeza como chromedp:

import (
    "context"
    "github.com/chromedp/chromedp"
)

func main() {
    ctx, cancel := chromedp.NewContext(context.Background())
    defer cancel()

    var res string
    err := chromedp.Run(ctx,
        chromedp.Navigate("http://example.com"),
        chromedp.WaitVisible(`#some-element`),
        chromedp.InnerHTML(`#some-element`, &res),
    )

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

12. Conclusión

A través de la introducción detallada de este artículo, hemos aprendido cómo utilizar Go 1.19 para implementar una herramienta automatizada simplificada de rastreo de plantillas de sitios. Comenzamos desde el proceso básico de diseño del rastreador y gradualmente profundizamos en aspectos clave como el análisis HTML, el procesamiento concurrente, el almacenamiento de datos y el manejo de errores, y demostramos cómo rastrear y procesar datos de páginas web a través de ejemplos de código específicos.

Las poderosas capacidades de procesamiento concurrente del lenguaje Go y las ricas bibliotecas de terceros lo convierten en una opción ideal para crear rastreadores web eficientes y estables. Mediante la optimización y expansión continuas, se pueden lograr funciones de rastreador más complejas y avanzadas para proporcionar soluciones para diversas necesidades de recopilación de datos.

Espero que este artículo pueda brindarle una referencia valiosa para implementar rastreadores web en lenguaje Go y lo inspire a realizar más exploración e innovación en este campo.