Распарсить html-страницу на Go
Мы будем использовать библиотеку GoQuery, которая предоставляет удобный API для парсинга HTML, похожий на jQuery.
Если у вас еще не установлена библиотека, установите ее с помощью:
go get github.com/PuerkitoBio/goquery
Рассмотрим пример, в котором мы:
- Загружаем HTML-страницу (это может быть строка, файл или HTTP-ответ)
- Парсим ее с помощью goquery
- Извлекаем нужные данные (например, по селекторам)
Пример: распарсим HTML из строки и извлечем все ссылки (теги ), выведем их текст и атрибут href.
Для парсинга HTML-страниц в Go рекомендуется использовать библиотеку goquery. Вот пошаговое руководство:
1. Установите библиотеку goquery
go get github.com/PuerkitoBio/goquery
2. Базовый пример парсинга
package main import ( "fmt" "log" "strings" "github.com/PuerkitoBio/goquery" ) func main() { // Пример HTML-контента (может быть заменен на http.Request или файл) html := `
ЗаголовокЭлемент 1Элемент 2Ссылка ` // Создание документа из строки doc, err := goquery.NewDocumentFromReader(strings.NewReader(html)) if err != nil { log.Fatal("Ошибка парсинга:", err) } // Пример 1: Извлечение заголовка title := doc.Find("h1").Text() fmt.Println("Заголовок:", title) // Пример 2: Парсинг списка doc.Find("ul.list li").Each(func(i int, s *goquery.Selection) { fmt.Printf("Элемент %d: %s\n", i+1, s.Text()) }) // Пример 3: Получение атрибутов link, exists := doc.Find("a").Attr("href") if exists { fmt.Println("Ссылка:", link) } }
3. Парсинг веб-страницы по URL
func parseFromURL() { doc, err := goquery.NewDocument("https://example.com") if err != nil { log.Fatal(err) } // Пример: извлечение всех ссылок doc.Find("a").Each(func(_ int, s *goquery.Selection) { href, exists := s.Attr("href") if exists { fmt.Println(href) } }) }
Ключевые методы goquery:
- Find(selector) - поиск элементов по CSS-селектору
- Text() - получение текстового содержимого
- Attr(name) - получение значения атрибута
- Each() - итерация по набору элементов
- Html() - получение внутреннего HTML
Особенности:
- Обработка ошибок: Всегда проверяйте ошибки при создании документа
- Цепочки вызовов: Методы можно объединять в цепочки: goCopyDownloaddoc.Find("div.content").First().Find("p").Text()
- Фильтрация:
- goCopyDownloaddoc.Find("tr").Filter(":nth-child(even)") // Четные строки таблицы
Аналоги для сложных случаев:
- Для низкоуровневой работы используйте golang.org/x/net/html
- Для JavaScript-heavy страниц используйте chromedp (эмуляция браузера)
Пример с извлечением данных в структуру:
type Item struct { Title string Link string } func parseItems(doc *goquery.Document) []Item { var items []Item doc.Find(".item").Each(func(_ int, s *goquery.Selection) { title := s.Find(".title").Text() link, _ := s.Find("a").Attr("href") items = append(items, Item{title, link}) }) return items }
Важно: Всегда проверяйте robots.txt сайта и соблюдайте политику сканирования. Используйте кеширование и задержки при массовом парсинге.