Парсинг HTML в Go (Golang): обзор библиотек и практические примеры
Go (Golang) — это компилируемый, статически типизированный язык, который отлично подходит для создания высокопроизводительных инструментов веб-скрапинга и парсинга HTML. Встроенная стандартная библиотека net/html предоставляет низкоуровневый токенизатор, однако для удобной работы с DOM-деревом и CSS-селекторами чаще используют сторонние пакеты. В этой статье мы разберём три ключевых инструмента: goquery, colly и стандартный пакет net/html. Вы узнаете, как выбрать подходящий инструмент, и увидите рабочие примеры кода.
1. Стандартная библиотека: net/html
Пакет golang.org/x/net/html предоставляет токенизатор и парсер HTML. Он реализует спецификацию HTML5 и позволяет разбирать документ в дерево узлов. Это самый лёгкий и быстрый вариант, но требует написания большего количества кода для навигации.
Пример: извлечение всех ссылок (<a href>) со страницы:
package main
import (
"fmt"
"golang.org/x/net/html"
"net/http"
"strings"
)
func main() {
resp, _ := http.Get("https://example.com")
defer resp.Body.Close()
doc, _ := html.Parse(resp.Body)
var links []string
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" {
links = append(links, attr.Val)
}
}
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
f(c)
}
}
f(doc)
fmt.Println(strings.Join(links, "\n"))
}
Плюсы: минимальные зависимости, высокая скорость.
Минусы: нет CSS-селекторов, нужно писать рекурсивные обходчики.
2. goquery — jQuery для Go
goquery — самая популярная библиотека для парсинга HTML в Go. Она использует net/html под капотом и добавляет синтаксис, похожий на jQuery. Вы можете использовать CSS-селекторы для поиска элементов, цепочки вызовов и манипуляции с DOM.
Установка:
go get github.com/PuerkitoBio/goquery
Пример: сбор заголовков статей с блога:
package main
import (
"fmt"
"github.com/PuerkitoBio/goquery"
"log"
"net/http"
)
func main() {
resp, err := http.Get("https://habr.com/ru/all/")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
log.Fatal(err)
}
doc.Find("article h2").Each(func(i int, s *goquery.Selection) {
title := s.Text()
link, _ := s.Find("a").Attr("href")
fmt.Printf("%d. %s\n %s\n", i+1, title, link)
})
}
Основные методы goquery:
Find(selector)— поиск элементов по CSS-селекторуEach(func)— итерация по найденным элементамAttr(name)— получение значения атрибутаText()— извлечение текстового содержимогоHtml()— получение HTML-кода внутри элемента
goquery идеален для быстрого прототипирования и парсинга страниц со сложной структурой. Однако помните: он не поддерживает выполнение JavaScript — это инструмент для статического HTML.
3. Colly — фреймворк для веб-скрапинга
Colly — это мощный фреймворк, который включает в себя не только парсинг HTML (через goquery), но и управление очередью запросов, работу с куками, лимитами скорости, кэшированием и параллельными запросами. Colly рекомендуется для масштабных проектов сбора данных.
Установка:
go get github.com/gocolly/colly/v2
Пример: парсинг всех заголовков с нескольких страниц:
package main
import (
"fmt"
"github.com/gocolly/colly/v2"
)
func main() {
c := colly.NewCollector(
colly.AllowedDomains("example.com"),
)
c.OnHTML("h2", func(e *colly.HTMLElement) {
fmt.Println(" Также в библиотеке
Dependency Injection контейнер для C# (.NET) — полное руководство
Работа с Apache Kafka в C++: библиотека librdkafka и практические примеры
Eigen для C++: полное руководство с примерами
Геолокация и карты в Node.js: библиотеки для работы с картами
Реактивное программирование в Swift: Combine и RxSwift для iOS/macOS