Парсинг HTML в Go (Golang): инструменты и практические примеры
Go (Golang) — это компилируемый, статически типизированный язык, созданный в Google. Благодаря высокой производительности, встроенной поддержке конкурентности и богатой стандартной библиотеке, Go стал одним из лучших языков для веб-скрапинга и парсинга HTML. В этой статье мы разберём основные библиотеки для работы с HTML-документами в Go, приведём примеры кода и сравним их возможности.
Зачем парсить HTML в Go?
Парсинг HTML необходим для извлечения данных с веб-страниц: новостей, цен, контактной информации, результатов поиска. Go отлично подходит для этой задачи благодаря:
- Высокой скорости выполнения (компилируется в машинный код)
- Лёгкой работе с сетью (встроенный пакет
net/http) - Простоте разбора DOM-дерева через специализированные библиотеки
- Отличной поддержке многопоточности (горутины и каналы)
Основные библиотеки для парсинга HTML в Go
1. net/html — стандартная библиотека
golang.org/x/net/html — это низкоуровневый токенизатор и парсер HTML из стандартной библиотеки Go. Он предоставляет полный контроль над процессом разбора, но требует написания большего количества кода.
Пример: извлечение всех ссылок (<a href>) из HTML-документа.
package main
import (
"fmt"
"golang.org/x/net/html"
"net/http"
"log"
)
func main() {
resp, err := http.Get("https://example.com")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
doc, err := html.Parse(resp.Body)
if err != nil {
log.Fatal(err)
}
var f func(*html.Node)
f = func(n *html.Node) {
if n.Type == html.ElementNode && n.Data == "a" {
for _, attr := range n.Attr {
if attr.Key == "href" {
fmt.Println(attr.Val)
}
}
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
f(c)
}
}
f(doc)
}
Плюсы: не требует установки сторонних пакетов, полный контроль. Минусы: много шаблонного кода, неудобно для сложных селекторов.
2. goquery — jQuery-подобный синтаксис
github.com/PuerkitoBio/goquery — самая популярная библиотека для парсинга HTML в Go. Она предоставляет API, похожий на jQuery: Find(), Each(), Attr(), Text().
Пример: парсинг заголовков новостей с сайта.
package main
import (
"fmt"
"github.com/PuerkitoBio/goquery"
"log"
"net/http"
)
func main() {
resp, err := http.Get("https://habr.com/ru/news/")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
log.Fatal(err)
}
doc.Find("h2.tm-article-snippet__title").Each(func(i int, s *goquery.Selection) {
title := s.Find("a").Text()
link, _ := s.Find("a").Attr("href")
fmt.Printf("%d. %s\n Ссылка: %s\n", i+1, title, link)
})
}
Плюсы: простой синтаксис, поддержка CSS-селекторов, богатая документация. Минусы: не подходит для очень больших документов (загружает всё в память).
3. colly — фреймворк для веб-скрапинга
github.com/gocolly/colly — это мощный фреймворк для сбора данных. Он включает парсинг HTML (на основе goquery), управление очередью запросов, обработку cookies, лимиты скорости и многое другое.
Пример: сбор всех ссылок с первой страницы сайта с задержкой между запросами.
package main
import (
"fmt"
"github.com/gocolly/colly/v2"
)
func main() {
c := colly.NewCollector(
colly.AllowedDomains("example.com"),
)
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
link := e.Attr("href")
fmt.Println("Найдена ссылка:", link)
})
c.OnRequest(func(r *colly.Request) {
fmt.Println("Посещаем:", r.URL)
})
c.Visit("https://example.com")
}
Плюсы: готовое решение для сложных проектов, встроенная обработка ошибок, поддержка пагинации. Ми
Также в библиотеке
Dependency Injection контейнер для C# (.NET) — полное руководство
Pistache для C++: полное руководство с примерами
Конфигурация приложений C# (.NET): библиотеки и инструменты
Тестирование в TypeScript: Полное руководство по фреймворкам и инструментам
WireMock для Java: полное руководство с примерами