私の連絡先情報
郵便メール:
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Web Scraper は、Web サイトからデータを自動的に抽出するツールです。データ収集、検索エンジンの最適化、市場調査などの分野で広く使用されています。この記事では、Go 1.19 を使用して、開発者が効率的にデータを収集できるように、簡素化された自動サイト テンプレート クロール ツールを実装する方法を詳しく紹介します。
始める前に、システムに Go 1.19 がインストールされていることを確認してください。 Go のバージョンは次のコマンドで確認できます。
go version
Go をまだインストールしていない場合は、次からダウンロードできます。 ゴー公式サイト 最新バージョンをダウンロードしてインストールします。
Web クローラーの基本的なワークフローは次のとおりです。
Go 言語には、次のような人気のあるクローラー フレームワークがいくつかあります。
この記事では、主に Web クローリングとコンテンツ解析に Colly と Goquery を使用します。
簡素化された自動サイト テンプレート クロール ツールを設計します。基本的なプロセスは次のとおりです。
まず、新しい Go プロジェクトを作成します。
mkdir go_scraper
cd go_scraper
go mod init go_scraper
次に、Colly と Goquery をインストールします。
go get -u github.com/gocolly/colly
go get -u github.com/PuerkitoBio/goquery
次に、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")
}
上記のコードを実行すると、http://example.com のコンテンツがクロールされ、ページ タイトルが出力されます。
Web ページから必要なデータを抽出するには、Goquery を使用して HTML コンテンツを解析する必要があります。次の例は、Goquery を使用して 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")
}
クローラーの効率を向上させるために、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() // 等待所有异步任务完成
}
キャプチャしたデータをローカル ファイルまたはデータベースに保存します。 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()
}
クローラーの安定性を向上させるには、リクエスト エラーを処理し、再試行メカニズムを実装する必要があります。
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()
}
次の例は、ニュース Web サイトのタイトルとリンクをスクレイピングして 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()
}
ターゲット Web サイトによってブロックされないようにするには、プロキシを使用できます。
c.SetProxy("http://proxyserver:port")
ユーザー エージェントを設定して、別のブラウザーのふりをします。
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"
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)
}
動的な Web ページの場合は、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)
}
この記事の詳細な紹介を通じて、Go 1.19 を使用して簡略化された自動サイト テンプレート クロール ツールを実装する方法を学びました。基本的なクローラー設計プロセスから開始し、HTML 解析、同時処理、データ ストレージ、エラー処理などの主要な側面に徐々に進み、特定のコード例を通じて Web ページ データをクロールおよび処理する方法を示しました。
Go 言語の強力な同時処理機能と豊富なサードパーティ ライブラリにより、Go 言語は効率的で安定した Web クローラーを構築するのに理想的な選択肢となります。継続的な最適化と拡張により、より複雑かつ高度なクローラ機能を実現し、さまざまなデータ収集ニーズに対するソリューションを提供します。
この記事が、Go 言語で Web クローラーを実装するための貴重な参考資料となり、この分野でさらなる探索と革新を行うきっかけになれば幸いです。