моя контактная информация
Почтамезофия@protonmail.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 и вдохновить вас на дальнейшие исследования и инновации в этой области.