Partage de technologie

Framework d'exploration Go1.19 : simplifiez l'exploration automatisée des modèles de sites

2024-07-12

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

introduction

Web Scraper est un outil qui extrait automatiquement les données des sites Web. Ils sont largement utilisés dans la collecte de données, l’optimisation des moteurs de recherche, les études de marché et d’autres domaines. Cet article présentera en détail comment utiliser Go 1.19 pour implémenter un outil d'exploration automatisé simplifié de modèles de site afin d'aider les développeurs à collecter efficacement des données.

Table des matières

  1. Préparation environnementale
  2. Concepts de base des robots d'exploration Web
  3. Aller à la sélection du framework d'exploration
  4. Processus de base de conception d'un robot
  5. Implémenter un robot d'exploration Web simple
  6. Analyser le contenu HTML
  7. Traitement simultané des robots d'exploration
  8. stockage de données
  9. Mécanisme de gestion des erreurs et de nouvelle tentative
  10. Cas pratique : crawl de sites d'actualités
  11. Fonctionnalités avancées et optimisations
  12. en conclusion

1. Préparation de l'environnement

Avant de commencer, assurez-vous que Go 1.19 est installé sur votre système. Vous pouvez vérifier la version Go avec la commande suivante :

go version
  • 1

Si vous n'avez pas encore installé Go, vous pouvez le télécharger depuis Aller sur le site officiel Téléchargez et installez la dernière version.

2. Concepts de base des robots d'exploration Web

Le flux de travail de base d'un robot d'exploration Web est le suivant :

  1. envoyer une demande: Envoyez une requête HTTP à la page Web cible.
  2. Avoir une réponse: Recevez la réponse HTTP renvoyée par le serveur.
  3. analyser le contenu : Extrayez les données requises de la réponse.
  4. Stocker des données: Enregistrez les données extraites dans un fichier local ou une base de données.
  5. Gérer les liens : extrayez les liens des pages Web et continuez à explorer d'autres pages.

3. Aller à la sélection du framework d'exploration

Dans le langage Go, il existe plusieurs frameworks de robots d'exploration populaires, tels que :

  • Colly : un framework de robots d'exploration rapide et élégant qui offre des fonctionnalités riches et de bonnes performances.
  • Goquery : une bibliothèque de type jQuery pour analyser et manipuler des documents HTML.
  • Client HTTP : Le package net/http de la bibliothèque standard peut répondre aux besoins de requêtes HTTP les plus simples.

Cet article utilisera principalement Colly et Goquery pour l'exploration du Web et l'analyse du contenu.

4. Processus de base de conception d'un robot

Nous allons concevoir un outil d'exploration automatisé et simplifié de modèles de sites. Le processus de base est le suivant :

  1. Initialisez la configuration du robot.
  2. Envoyez une requête HTTP pour obtenir le contenu de la page Web.
  3. Utilisez Goquery pour analyser le contenu HTML et extraire les données requises.
  4. Enregistrez les données dans un fichier local ou une base de données.
  5. Mécanismes de gestion des erreurs et de nouvelle tentative.
  6. Utilisez le traitement simultané pour améliorer l’efficacité de l’analyse.

5. Implémentez un robot d'exploration Web simple

Tout d’abord, créez un nouveau projet Go :

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

Ensuite, installez Colly et Goquery :

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

Ensuite, écrivez un robot d'exploration simple pour explorer le contenu 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

L'exécution du code ci-dessus explorera le contenu de http://example.com et imprimera le titre de la page.

6. Analyser le contenu HTML

Afin d'extraire les données requises de la page Web, nous devons utiliser Goquery pour analyser le contenu HTML. L'exemple suivant montre comment utiliser Goquery pour extraire des liens et du texte d'une page 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. Traitement simultané des robots d'exploration

Afin d'améliorer l'efficacité du robot, nous pouvons utiliser la fonction de concurrence 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. Stockage des données

Enregistrez les données capturées dans un fichier local ou une base de données. Voici un fichier CSV à titre d'exemple :

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. Mécanisme de gestion des erreurs et de nouvelle tentative

Afin d'améliorer la stabilité du robot, nous devons gérer les erreurs de requête et implémenter un mécanisme de nouvelle tentative :

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. Cas pratique : crawl de sites d'actualités

L'exemple suivant montre comment récupérer les titres et les liens d'un site Web d'actualités et les enregistrer dans un fichier 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. Fonctions avancées et optimisations

Utiliser un proxy

Pour éviter d'être bloqué par le site cible, vous pouvez utiliser un proxy :

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

Masquage de l'agent utilisateur

Faites semblant d'être un navigateur différent en définissant l'agent utilisateur :

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

Robot d'exploration distribué

Vous pouvez utiliser la bibliothèque d'extensions Colly-Redis pour implémenter des robots d'exploration distribués :

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

Scraping Web dynamique

Pour les pages Web dynamiques, vous pouvez utiliser un navigateur sans interface tel que 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. Conclusion

Grâce à l'introduction détaillée de cet article, nous avons appris à utiliser Go 1.19 pour implémenter un outil d'exploration automatisé et simplifié de modèles de sites. Nous sommes partis du processus de conception de base du robot d'exploration et avons progressivement abordé des aspects clés tels que l'analyse HTML, le traitement simultané, le stockage des données et la gestion des erreurs, et avons démontré comment explorer et traiter les données d'une page Web à l'aide d'exemples de code spécifiques.

Les puissantes capacités de traitement simultané du langage Go et ses riches bibliothèques tierces en font un choix idéal pour créer des robots d'exploration Web efficaces et stables. Grâce à une optimisation et une expansion continues, des fonctions d'exploration plus complexes et avancées peuvent être réalisées pour fournir des solutions à divers besoins de collecte de données.

J'espère que cet article pourra vous fournir une référence précieuse pour la mise en œuvre de robots d'exploration Web en langage Go et vous inciter à mener davantage d'exploration et d'innovation dans ce domaine.