내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Web Scraper는 웹사이트에서 자동으로 데이터를 추출하는 도구입니다. 이는 데이터 수집, 검색 엔진 최적화, 시장 조사 및 기타 분야에서 널리 사용됩니다. 이 기사에서는 Go 1.19를 사용하여 개발자가 효율적으로 데이터를 수집할 수 있도록 단순화된 자동화된 사이트 템플릿 크롤링 도구를 구현하는 방법을 자세히 소개합니다.
시작하기 전에 시스템에 Go 1.19가 설치되어 있는지 확인하세요. 다음 명령을 사용하여 Go 버전을 확인할 수 있습니다.
go version
아직 Go를 설치하지 않았다면 다음에서 다운로드할 수 있습니다. 공식 홈페이지로 이동 최신 버전을 다운로드하여 설치하세요.
웹 크롤러의 기본 작업 흐름은 다음과 같습니다.
Go 언어에는 다음과 같은 여러 가지 인기 있는 크롤러 프레임워크가 있습니다.
이 글에서는 주로 웹 크롤링과 콘텐츠 파싱을 위해 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
다음으로 웹 콘텐츠를 크롤링하는 간단한 크롤러를 작성합니다.
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의 콘텐츠가 크롤링되고 페이지 제목이 인쇄됩니다.
웹페이지에서 필요한 데이터를 추출하려면 Goquery를 사용하여 HTML 콘텐츠를 구문 분석해야 합니다. 다음 예에서는 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")
}
크롤러의 효율성을 향상시키기 위해 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()
}
다음 예에서는 뉴스 웹사이트의 제목과 링크를 스크랩하여 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()
}
대상 웹사이트의 차단을 방지하려면 프록시를 사용할 수 있습니다.
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)
}
동적 웹페이지의 경우 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 구문 분석, 동시 처리, 데이터 저장 및 오류 처리와 같은 주요 측면을 점차적으로 살펴보고 특정 코드 예제를 통해 웹 페이지 데이터를 크롤링하고 처리하는 방법을 시연했습니다.
Go 언어의 강력한 동시성 처리 기능과 풍부한 타사 라이브러리는 효율적이고 안정적인 웹 크롤러를 구축하는 데 이상적인 선택입니다. 지속적인 최적화와 확장을 통해 더욱 복잡하고 발전된 크롤러 기능을 구현하여 다양한 데이터 수집 요구에 맞는 솔루션을 제공할 수 있습니다.
이 기사가 Go 언어로 웹 크롤러를 구현하는 데 유용한 참고 자료를 제공하고 이 분야에서 더 많은 탐색과 혁신을 수행하도록 영감을 줄 수 있기를 바랍니다.