2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Web Scraper ist ein Tool, das automatisch Daten von Websites extrahiert. Sie werden häufig in der Datenerfassung, Suchmaschinenoptimierung, Marktforschung und anderen Bereichen eingesetzt. In diesem Artikel wird detailliert beschrieben, wie Sie mit Go 1.19 ein vereinfachtes automatisiertes Tool zum Crawlen von Site-Vorlagen implementieren, um Entwicklern dabei zu helfen, Daten effizient zu sammeln.
Stellen Sie vor dem Start sicher, dass Go 1.19 auf Ihrem System installiert ist. Sie können die Go-Version mit dem folgenden Befehl überprüfen:
go version
Wenn Sie Go noch nicht installiert haben, können Sie es hier herunterladen Gehen Sie zur offiziellen Website Laden Sie die neueste Version herunter und installieren Sie sie.
Der grundlegende Arbeitsablauf eines Webcrawlers ist wie folgt:
In der Go-Sprache gibt es mehrere beliebte Crawler-Frameworks, wie zum Beispiel:
In diesem Artikel werden Colly und Goquery hauptsächlich zum Web-Crawling und zum Parsen von Inhalten verwendet.
Wir werden ein vereinfachtes automatisiertes Tool zum Crawlen von Site-Vorlagen entwerfen. Der grundlegende Prozess ist wie folgt:
Erstellen Sie zunächst ein neues Go-Projekt:
mkdir go_scraper
cd go_scraper
go mod init go_scraper
Installieren Sie dann Colly und Goquery:
go get -u github.com/gocolly/colly
go get -u github.com/PuerkitoBio/goquery
Schreiben Sie als Nächstes einen einfachen Crawler zum Crawlen von Webinhalten:
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")
}
Wenn Sie den obigen Code ausführen, wird der Inhalt von http://example.com gecrawlt und der Seitentitel gedruckt.
Um die erforderlichen Daten von der Webseite zu extrahieren, müssen wir Goquery verwenden, um den HTML-Inhalt zu analysieren. Das folgende Beispiel zeigt, wie Sie mit Goquery Links und Text aus einer Webseite extrahieren:
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")
}
Um die Effizienz des Crawlers zu verbessern, können wir die Parallelitätsfunktion von Colly verwenden:
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() // 等待所有异步任务完成
}
Speichern Sie die erfassten Daten in einer lokalen Datei oder Datenbank. Hier ist eine CSV-Datei als Beispiel:
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()
}
Um die Stabilität des Crawlers zu verbessern, müssen wir Anforderungsfehler behandeln und einen Wiederholungsmechanismus implementieren:
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()
}
Das folgende Beispiel zeigt, wie Sie die Titel und Links einer Nachrichten-Website extrahieren und in einer CSV-Datei speichern:
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()
}
Um eine Blockierung durch die Zielwebsite zu vermeiden, können Sie einen Proxy verwenden:
c.SetProxy("http://proxyserver:port")
Geben Sie vor, ein anderer Browser zu sein, indem Sie den Benutzeragenten festlegen:
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"
Sie können Collys Erweiterungsbibliothek Colly-Redis verwenden, um verteilte Crawler zu implementieren:
import (
"github.com/gocolly/redisstorage"
)
func main() {
c := colly.NewCollector()
redisStorage := &redisstorage.Storage{
Address: "localhost:6379",
Password: "",
DB: 0,
Prefix: "colly",
}
c.SetStorage(redisStorage)
}
Für dynamische Webseiten können Sie einen Headless-Browser wie chromedp verwenden:
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)
}
Durch die ausführliche Einführung dieses Artikels haben wir gelernt, wie man mit Go 1.19 ein vereinfachtes automatisiertes Tool zum Crawlen von Site-Vorlagen implementiert. Wir begannen mit dem grundlegenden Crawler-Designprozess und vertieften uns nach und nach in wichtige Aspekte wie HTML-Parsing, gleichzeitige Verarbeitung, Datenspeicherung und Fehlerbehandlung und demonstrierten anhand spezifischer Codebeispiele, wie Webseitendaten gecrawlt und verarbeitet werden.
Die leistungsstarken Funktionen zur Parallelitätsverarbeitung und die umfangreichen Bibliotheken von Drittanbietern machen die Go-Sprache zur idealen Wahl für die Entwicklung effizienter und stabiler Webcrawler. Durch kontinuierliche Optimierung und Erweiterung können komplexere und fortschrittlichere Crawler-Funktionen erreicht werden, um Lösungen für verschiedene Datenerfassungsanforderungen bereitzustellen.
Ich hoffe, dieser Artikel kann Ihnen wertvolle Hinweise zur Implementierung von Webcrawlern in der Go-Sprache geben und Sie zu weiteren Erkundungen und Innovationen in diesem Bereich inspirieren.