प्रौद्योगिकी साझेदारी

Go1.19 क्रॉलर फ्रेमवर्क: साइट् टेम्पलेट् इत्यस्य स्वचालितक्रॉलिंग् सरलीकरोतु

2024-07-12

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

आमुख

Web Scraper इति एकं साधनं यत् स्वयमेव जालपुटेभ्यः आँकडान् निष्कासयति । तेषां उपयोगः आँकडासंग्रहणं, अन्वेषणयन्त्रस्य अनुकूलनं, विपण्यसंशोधनम् इत्यादिषु क्षेत्रेषु बहुधा भवति । अस्मिन् लेखे विस्तरेण परिचयः भविष्यति यत् विकासकानां कुशलतापूर्वकं आँकडानां संग्रहणं कर्तुं सहायतार्थं सरलीकृतं स्वचालितं साइट् टेम्पलेट् क्रॉलिंग् साधनं कार्यान्वितुं Go 1.19 इत्यस्य उपयोगः कथं भवति

सामग्रीसूची

  1. पर्यावरणसज्जता
  2. जालक्रॉलरस्य मूलभूतसंकल्पना
  3. क्रॉलर फ्रेमवर्क चयनं गच्छतु
  4. क्रॉलरस्य डिजाइनस्य मूलभूतप्रक्रिया
  5. सरलं जालक्रॉलरं कार्यान्वितं कुर्वन्तु
  6. HTML सामग्रीं विश्लेषणं कुर्वन्तु
  7. क्रॉलरस्य समवर्तीप्रक्रियाकरणम्
  8. दत्तांशसञ्चयम्
  9. त्रुटिनियन्त्रणं पुनः प्रयासं च तन्त्रम्
  10. व्यावहारिकः प्रकरणः : क्रॉलिंग् न्यूज वेबसाइट्
  11. उन्नतविशेषताः अनुकूलनानि च
  12. उपसंहारे

1. पर्यावरणस्य सज्जता

आरम्भात् पूर्वं सुनिश्चितं कुर्वन्तु यत् भवतां प्रणाल्यां Go 1.19 संस्थापितम् अस्ति । भवन्तः निम्नलिखित आदेशेन Go संस्करणं पश्यितुं शक्नुवन्ति ।

go version
  • 1

यदि भवान् अद्यापि Go इत्येतत् न संस्थापितवान् तर्हि तस्मात् डाउनलोड् कर्तुं शक्नोति आधिकारिकजालस्थलं गच्छन्तु नवीनतमं संस्करणं डाउनलोड् कृत्वा संस्थापयन्तु।

2. जालक्रॉलरस्य मूलभूतसंकल्पना

जालक्रॉलरस्य मूलभूतः कार्यप्रवाहः निम्नलिखितरूपेण भवति ।

  1. अनुरोधं प्रेषयतु: लक्ष्यजालपृष्ठे HTTP अनुरोधं प्रेषयन्तु।
  2. प्रतिक्रिया प्राप्नुत: सर्वरेण प्रत्यागतं HTTP प्रतिक्रियां प्राप्नुवन्तु।
  3. सामग्रीं विश्लेषणं कुर्वन्तु: प्रतिक्रियातः आवश्यकं दत्तांशं निष्कासयन्तु।
  4. दत्तांशस्य संग्रहणम्: निष्कासितं दत्तांशं स्थानीयसञ्चिकायां वा दत्तांशकोशे वा रक्षन्तु ।
  5. लिङ्कानि सम्पादयन्तु: जालपुटेभ्यः लिङ्कानि निष्कास्य अन्यपृष्ठानि क्रॉलं निरन्तरं कुर्वन्तु।

3. क्रॉलर फ्रेमवर्क चयनं गच्छन्तु

Go भाषायां अनेकाः लोकप्रियाः क्रॉलर-रूपरेखाः सन्ति, यथा-

  • कोली : एकः द्रुतः सुरुचिपूर्णः च क्रॉलर-रूपरेखा यः समृद्धं कार्यक्षमतां उत्तमं प्रदर्शनं च प्रदाति ।
  • Goquery: HTML दस्तावेजानां विश्लेषणार्थं, हेरफेरार्थं च jQuery-सदृशं पुस्तकालयम् ।
  • HTTP क्लायन्ट् : मानकपुस्तकालयस्य net/http संकुलं अधिकांशं सरलं HTTP अनुरोधस्य आवश्यकतां पूरयितुं शक्नोति ।

अयं लेखः मुख्यतया जालक्रॉलिंग् तथा सामग्रीपार्सिंग् कृते Colly तथा Goquery इत्येतयोः उपयोगं करिष्यति ।

4. क्रॉलरस्य डिजाइनस्य मूलभूतप्रक्रिया

वयं सरलीकृतं स्वचालितं साइट् टेम्पलेट् क्रॉलिंग् टूल् डिजाइनं करिष्यामः मूलभूतप्रक्रिया निम्नलिखितरूपेण अस्ति ।

  1. क्रॉलर विन्यासः आरभत।
  2. जालपुटस्य सामग्रीं प्राप्तुं HTTP अनुरोधं प्रेषयन्तु ।
  3. HTML सामग्रीं विश्लेषयितुं आवश्यकं दत्तांशं निष्कासयितुं Goquery इत्यस्य उपयोगं कुर्वन्तु ।
  4. स्थानीयसञ्चिकायां अथवा दत्तांशकोशे दत्तांशं रक्षन्तु ।
  5. त्रुटिनियन्त्रणं पुनः प्रयासं च तन्त्रम् ।
  6. क्रॉलिंग्-दक्षतां वर्धयितुं समवर्ती-प्रक्रियाकरणस्य उपयोगं कुर्वन्तु ।

5. सरलं जालक्रॉलरं कार्यान्वितं कुर्वन्तु

प्रथमं नूतनं Go परियोजना रचयन्तु :

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

ततः, Colly and Goquery संस्थापयन्तु:

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

तदनन्तरं जालसामग्री क्रॉल कर्तुं सरलं क्रॉलरं लिखन्तु :

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

उपर्युक्तं कोडं चालयित्वा http://example.com इत्यस्य सामग्रीं क्रॉल कृत्वा पृष्ठस्य शीर्षकं मुद्रयिष्यति ।

6. HTML सामग्रीं विश्लेषणं कुर्वन्तु

जालपुटात् आवश्यकं दत्तांशं निष्कासयितुं अस्माभिः HTML सामग्रीं विश्लेषयितुं Goquery इत्यस्य उपयोगः आवश्यकः । निम्नलिखित उदाहरणं दर्शयति यत् जालपुटात् लिङ्क् पाठं च निष्कासयितुं Goquery इत्यस्य उपयोगः कथं भवति ।

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. क्रॉलरस्य समवर्ती संसाधनम्

क्रॉलरस्य कार्यक्षमतां वर्धयितुं वयं 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. दत्तांशसञ्चयः

गृहीतदत्तांशं स्थानीयसञ्चिकायां वा दत्तांशकोशे वा रक्षन्तु । अत्र उदाहरणरूपेण CSV सञ्चिका अस्ति ।

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. त्रुटिनियन्त्रणं पुनः प्रयासं च तन्त्रम्

क्रॉलरस्य स्थिरतां सुधारयितुम् अस्माभिः अनुरोधदोषान् नियन्त्रयितुं पुनः प्रयासं तन्त्रं च कार्यान्वितुं आवश्यकम्:

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. व्यावहारिकः प्रकरणः : क्रॉलिंग् न्यूज वेबसाइट्

निम्नलिखित उदाहरणं दर्शयति यत् कथं वार्ताजालस्थलस्य शीर्षकाणि लिङ्कानि च स्क्रैप् कृत्वा 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. उन्नतकार्यं अनुकूलनं च

प्रॉक्सी इत्यस्य उपयोगं कुर्वन्तु

लक्ष्यजालस्थलेन अवरुद्धं न भवितुं भवान् प्रॉक्सी उपयोक्तुं शक्नोति:

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

उपयोक्ता एजेण्ट् मुखौटा

उपयोक्तृ-एजेण्टं सेट् कृत्वा भिन्न-ब्राउजर्-रूपेण अभिनयं कुर्वन्तु:

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

वितरित क्रॉलर

वितरितक्रॉलर्-कार्यं कर्तुं भवान् Colly इत्यस्य विस्तारपुस्तकालयस्य Colly-Redis इत्यस्य उपयोगं कर्तुं शक्नोति:

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

गतिशील जाल स्क्रैपिंग

गतिशीलजालपृष्ठानां कृते, भवान् 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. उपसंहारः

अस्य लेखस्य विस्तृतपरिचयस्य माध्यमेन वयं सरलीकृतं स्वचालितं साइट् टेम्पलेट् क्रॉलिंग् साधनं कार्यान्वितुं Go 1.19 इत्यस्य उपयोगं कथं कर्तव्यमिति ज्ञातवन्तः । वयं मूलभूतक्रॉलर-डिजाइन-प्रक्रियातः आरब्धाः क्रमेण HTML-पार्सिंग्, समवर्ती-प्रक्रियाकरणं, आँकडा-भण्डारणं, त्रुटि-नियन्त्रणं च इत्यादिषु प्रमुखेषु पक्षेषु गतवन्तः, विशिष्ट-सङ्केत-उदाहरणानां माध्यमेन जालपुट-दत्तांशं क्रॉल-प्रक्रियाकरणं च कथं करणीयम् इति प्रदर्शितवन्तः

गो भाषायाः शक्तिशालिनः समवर्तीप्रक्रियाक्षमता तथा समृद्धाः तृतीयपक्षपुस्तकालयाः च कुशलस्य स्थिरस्य च जालक्रॉलरस्य निर्माणार्थं आदर्शविकल्पं कुर्वन्ति निरन्तरं अनुकूलनस्य विस्तारस्य च माध्यमेन विविधदत्तांशसङ्ग्रहस्य आवश्यकतानां समाधानं प्रदातुं अधिकजटिलानि उन्नतानि च क्रॉलरकार्यं प्राप्तुं शक्यते ।

आशासे यत् एषः लेखः भवद्भ्यः Go भाषायां जालक्रॉलर-कार्यन्वयनार्थं बहुमूल्यं सन्दर्भं प्रदातुं शक्नोति तथा च अस्मिन् क्षेत्रे अधिकं अन्वेषणं नवीनतां च कर्तुं प्रेरयितुं शक्नोति।