Teknologian jakaminen

Go1.19-indeksointikehys: yksinkertaista sivustomallien automaattista indeksointia

2024-07-12

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

esittely

Web Scraper on työkalu, joka poimii tiedot automaattisesti verkkosivustoilta. Niitä käytetään laajasti tiedonkeruussa, hakukoneoptimoinnissa, markkinatutkimuksessa ja muilla aloilla. Tässä artikkelissa esitellään yksityiskohtaisesti, miten Go 1.19:n avulla voidaan ottaa käyttöön yksinkertaistettu automatisoitu sivustomallien indeksointityökalu, joka auttaa kehittäjiä keräämään tietoja tehokkaasti.

Sisällysluettelo

  1. Ympäristön valmistelu
  2. Verkkoindeksointirobottien peruskäsitteet
  3. Siirry indeksointikehyksen valintaan
  4. Indeksointirobotin suunnittelun perusprosessi
  5. Ota käyttöön yksinkertainen indeksointirobotti
  6. Jäsennä HTML-sisältöä
  7. Indeksointirobottien samanaikainen käsittely
  8. tietovarasto
  9. Virheenkäsittely- ja uudelleenyritysmekanismi
  10. Käytännön tapaus: uutissivustojen indeksointi
  11. Lisäominaisuudet ja optimoinnit
  12. tiivistettynä

1. Ympäristön valmistelu

Ennen kuin aloitat, varmista, että järjestelmääsi on asennettu Go 1.19. Voit tarkistaa Go-version seuraavalla komennolla:

go version
  • 1

Jos et ole vielä asentanut Goa, voit ladata sen osoitteesta Mene viralliselle verkkosivustolle Lataa ja asenna uusin versio.

2. Verkkoindeksointirobottien peruskäsitteet

Verkkoindeksointirobotin perustyönkulku on seuraava:

  1. Lähetä pyyntö: Lähetä HTTP-pyyntö kohdeverkkosivulle.
  2. Hanki vastaus: Vastaanota palvelimen palauttama HTTP-vastaus.
  3. jäsentää sisältöä: Pura vaaditut tiedot vastauksesta.
  4. Tietojen tallentaminen: Tallenna puretut tiedot paikalliseen tiedostoon tai tietokantaan.
  5. Käsittele linkkejä: Poimi linkit verkkosivuilta ja jatka muiden sivujen indeksointia.

3. Siirry indeksointikehyksen valintaan

Go-kielellä on useita suosittuja indeksointikehyksiä, kuten:

  • Colly: Nopea ja tyylikäs indeksointikehys, joka tarjoaa runsaasti toimintoja ja hyvän suorituskyvyn.
  • Goquery: jQueryn kaltainen kirjasto HTML-dokumenttien jäsentämiseen ja käsittelyyn.
  • HTTP-asiakas: Vakiokirjaston net/http-paketti voi täyttää useimmat yksinkertaiset HTTP-pyyntötarpeet.

Tämä artikkeli käyttää pääasiassa Collya ja Goquerya verkkoindeksointiin ja sisällön jäsentämiseen.

4. Indeksoijan suunnittelun perusprosessi

Suunnittelemme yksinkertaistetun automatisoidun sivustomallin indeksointityökalun. Perusprosessi on seuraava:

  1. Alusta indeksointirobotin määritykset.
  2. Lähetä HTTP-pyyntö verkkosivun sisällön saamiseksi.
  3. Käytä Goquerya HTML-sisällön jäsentämiseen ja tarvittavien tietojen purkamiseen.
  4. Tallenna tiedot paikalliseen tiedostoon tai tietokantaan.
  5. Virheenkäsittely- ja uudelleenyritysmekanismit.
  6. Käytä samanaikaista käsittelyä parantaaksesi indeksoinnin tehokkuutta.

5. Ota käyttöön yksinkertainen indeksointirobotti

Luo ensin uusi Go-projekti:

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

Asenna sitten Colly ja Goquery:

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

Kirjoita seuraavaksi yksinkertainen indeksointirobotti verkkosisällön indeksoimiseksi:

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

Yllä olevan koodin suorittaminen indeksoi osoitteen http://example.com sisällön ja tulostaa sivun otsikon.

6. Jäsennä HTML-sisältöä

Jotta voimme poimia tarvittavat tiedot verkkosivulta, meidän on käytettävä Goquerya HTML-sisällön jäsentämiseen. Seuraava esimerkki näyttää, kuinka Goquerya käytetään linkkien ja tekstin poimimiseen verkkosivulta:

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. Indeksointirobottien samanaikainen käsittely

Indeksointirobotin tehokkuuden parantamiseksi voimme käyttää Collyn samanaikaisuusfunktiota:

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. Tietojen tallennus

Tallenna kaapatut tiedot paikalliseen tiedostoon tai tietokantaan. Tässä on esimerkkinä CSV-tiedosto:

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. Virheenkäsittely- ja uudelleenyritysmekanismi

Indeksointirobotin vakauden parantamiseksi meidän on käsiteltävä pyyntövirheet ja otettava käyttöön uudelleenyritysmekanismi:

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. Käytännön tapaus: uutissivustojen indeksointi

Seuraava esimerkki näyttää, kuinka uutissivuston otsikot ja linkit kaavitaan ja tallennetaan CSV-tiedostoon:

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. Kehittyneet toiminnot ja optimoinnit

Käytä välityspalvelinta

Jotta kohdesivusto ei estä sinua, voit käyttää välityspalvelinta:

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

Käyttäjäagentin naamiointi

Teeskentele olevasi eri selain asettamalla käyttäjäagentti:

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

Jaettu indeksointirobotti

Voit käyttää Collyn laajennuskirjastoa Colly-Redis toteuttaaksesi hajautettuja indeksointirobotteja:

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

Dynaaminen verkon kaavinta

Dynaamisille verkkosivuille voit käyttää päätöntä selainta, kuten chromedp:tä:

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. Johtopäätös

Tämän artikkelin yksityiskohtaisen esittelyn kautta olemme oppineet käyttämään Go 1.19:ää yksinkertaistetun automatisoidun sivustomallin indeksointityökalun toteuttamiseen. Aloitimme indeksointirobotin perussuunnitteluprosessista ja siirryimme vähitellen tärkeimpiin osiin, kuten HTML-jäsennykseen, samanaikaiseen käsittelyyn, tietojen tallentamiseen ja virheiden käsittelyyn, ja osoitimme, kuinka verkkosivujen tietoja indeksoidaan ja käsitellään tiettyjen koodiesimerkkien avulla.

Go-kielen tehokkaat samanaikaisuuden käsittelyominaisuudet ja monipuoliset kolmannen osapuolen kirjastot tekevät siitä ihanteellisen valinnan tehokkaiden ja vakaiden verkkoindeksointirobottien rakentamiseen. Jatkuvan optimoinnin ja laajentamisen avulla voidaan saavuttaa monimutkaisempia ja kehittyneempiä indeksointitoimintoja, jotka tarjoavat ratkaisuja erilaisiin tiedonkeruutarpeisiin.

Toivon, että tämä artikkeli voi tarjota sinulle arvokasta tietoa indeksointirobottien käyttöönotosta Go-kielellä ja innostaa sinua tutkimaan ja kehittämään enemmän tällä alalla.