Гид по технологиям

Веб-скрейпинг на Go с goquery: полное руководство

6 min read Программирование Обновлено 13 Dec 2025
Web scraping на Go с goquery — руководство
Web scraping на Go с goquery — руководство

HTML страницы сайта

Что такое веб-скрейпинг

Веб-скрейпинг, или извлечение веб-данных, — это автоматизированный способ получения содержимого веб-страниц. Скрейперы отправляют HTTP-запросы к сайту, получают HTML и затем извлекают нужные данные программно вместо того, чтобы отображать страницу пользователю.

Коротко: отправили запрос → получили HTML → распарсили → выбрали данные → сохранили.

Важно: перед запуском скрейпинга проверьте правила сайта (robots.txt) и юридические ограничения. Технически можно собрать почти любые данные, но правовые и этические границы соблюдать нужно всегда.

Для чего это нужно

  • Сбор данных для анализа и машинного обучения.
  • Мониторинг цен и доступности товаров.
  • Интеллектуальная собственность и исследования в кибербезопасности.
  • Интеграция данных с сервисами без открытого API.

Варианты библиотек для скрейпинга на Go

  • goquery — парсер HTML с API, похожим на jQuery, основан на net/html и Cascadia для селекторов CSS.
  • Colly — специализированная библиотека для веб-скрейпинга с удобной архитектурой, очередями и ограничениями скорости.
  • ChromeDP — драйвер, использующий Chrome DevTools Protocol; полезен для JavaScript-динамических страниц (headless Chrome).

Когда выбирать: если страница статическая — goquery быстрее и проще. Если нужна эмуляция браузера и выполнение JS — ChromeDP или Headless Chrome через Puppeteer/Playwright будут лучше. Colly хорош для распределённого или масштабного сбора.

Что такое goquery

goquery вдохновлён jQuery: он предоставляет удобные методы для навигации по дереву HTML и извлечения текста/атрибутов с помощью CSS-селекторов. Технически библиотека использует net/html для парсинга HTML5 и Cascadia для сопоставления селекторов.

Установка goquery

Откройте терминал и выполните:

go get github.com/PuerkitoBio/goquery

Если возникают ошибки — обновите версию Go и убедитесь, что GOPATH и модульные настройки корректны (go mod init/require).

Общая схема процесса скрейпинга

  1. Подготовить HTTP-запрос.
  2. Получить HTML-ответ.
  3. Распарсить HTML в документ goquery.
  4. Найти нужные элементы CSS-селекторами.
  5. Извлечь текст и атрибуты (href, src и т. п.).
  6. Сохранить результаты в структуру или БД.

Отправка HTTP-запроса в Go

В стандартной библиотеке есть пакет net/http. Простой пример запроса:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    webUrl := "https://news.ycombinator.com/"
    response, err := http.Get(webUrl)

    if err != nil {
        log.Fatalln(err)
    } else if response.StatusCode == 200 {
        fmt.Println("We can scrape this")
    } else {
        log.Fatalln("Do not scrape this")
    }
}

http.Get возвращает *http.Response и ошибку. Проверяйте response.StatusCode — при 200 можно продолжать обработку.

Заметка: в реальном проекте используйте http.Client с таймаутами и возможностью настройки заголовков (User-Agent, cookies), чтобы снизить риск блокировок.

Парсинг HTML и получение документа goquery

После успешного запроса нужно распарсить тело ответа в документ goquery:

document, err := goquery.NewDocumentFromReader(response.Body)
if err != nil {
    log.Fatalln(err)
}

document представляет DOM-дерево страницы и позволяет применять CSS-селекторы.

Как выбирать элементы с помощью селекторов

Прежде чем писать код, откройте страницу в браузере и изучите структуру (DevTools). Это поможет составить точные селекторы.

Просмотр структуры Hacker News в инструментах разработчика

Пример: найти строки с классом tr.athing:

document.Find("tr.athing")

Выборка нескольких элементов и обход

Чтобы получить все совпадения, используйте Each — она перебирает найденные элементы и вызывает функцию-обработчик:

document.Find("tr.athing").Each(func(index int, selector *goquery.Selection) {
    /* Обработка элемента selector */
})

Внутри обработчика вы можете уточнить выборку и извлечь текст или атрибуты:

document.Find("tr.athing").Each(func(index int, selector *goquery.Selection) {
    title := selector.Find("td.title").Text()
    link, found := selector.Find("a.titlelink").Attr("href")
    if found {
        // обработать link
    }
})

Text() возвращает текст внутри элемента. Attr возвращает значение атрибута и булево значение, указывающее, найден ли атрибут.

Совет: используйте strings.TrimSpace для очистки текста от лишних пробелов и невидимых символов.

Пример структуры данных и сохранение

Часто достаточно пользовательского struct и среза, чтобы аккумулировать результаты. Заметьте: если вы хотите кодировать данные в JSON или экспортировать поля, имена полей должны быть экспортируемыми (начинаться с заглавной буквы).

type Information struct {
    Link  string
    Title string
}

info := make([]Information, 0)

// Внутри Each:
// info = append(info, Information{Title: title, Link: link})

fmt.Println(info)

В реальных сценариях вы будете сохранять данные в базу (Postgres, MySQL через database/sql, MongoDB через официальный драйвер или в кеш на диске). Кеширование снижает нагрузку на исходный сервер и ускоряет повторные запросы.

Кейсы и альтернативные подходы

  • Статическая страница (HTML формируется на сервере): goquery + net/http — быстро и просто.
  • Динамическая страница (контент формируется JS): используйте ChromeDP или внешний headless-браузер (Playwright, Puppeteer) и забирайте уже отрендеренный DOM.
  • Масштабный сбор: Colly даёт встроенные механизмы ограничений скорости, очередей и параллелизации.

Контрпример: если сайт предлагает официальное API с нужными данными и ограничениями, лучше использовать API — это надежнее и легальнее.

Безопасность и этика

Важно:

  • Соблюдайте robots.txt и правила сайта.
  • Не отправляйте слишком много запросов за короткое время — используйте rate limiting.
  • Уважайте авторские права и персональные данные.

Риск блокировок минимизируется корректной настройкой заголовков, задержек и ротацией прокси, но прокси и обход ограничений должны использоваться с юридическим обоснованием.

Принципы тестирования и критерии приёмки

Критерии приёмки:

  • Скрипт корректно получает 200 OK и распарсивает документ.
  • Для каждой ожидаемой записи извлекаются title и link (не пустые).
  • Данные сохраняются в структуре или БД без ошибок записи.
  • Скрипт выдерживает базовую ошибку сети и повторяет попытку с экспоненциальной задержкой.

Примеры тестов:

  • Мокаем HTTP-ответ чартером с статическим HTML и проверяем, что срез info содержит N элементов.
  • Проверяем поведение при 404/500: обработка ошибки и логирование.

Производительность и зрелость решения

Уровни зрелости:

  • MVP: одиночный скрипт на goquery + net/http, сохраняющий в JSON/CSV.
  • Продакшн-минимум: добавить таймауты, ретраи, логирование и конфиг rate limits.
  • Масштаб: использовать Colly или распределённую очередь, хранить результаты в БД и следить за SLI/SLO (время отклика, успешные запросы).

Шаблон рабочей последовательности (мини-SOP)

  1. Описать цель сбора и поля для извлечения.
  2. Проанализировать структуру страницы в DevTools.
  3. Написать селекторы и локальные тесты на статическом HTML.
  4. Добавить обработку ошибок и повторные попытки.
  5. Настроить ограничения скорости и таймауты.
  6. Логировать метрики и ошибки, мониторить корректность данных.

Чеклист для разных ролей

Разработчик:

  • Написал модуль запросов с таймаутом.
  • Добавил парсер goquery и тесты на примерах HTML.
  • Экспортировал поля для сериализации.

DevOps:

  • Настроил очереди и ограничители запросов.
  • Развернул мониторинг и алерты на падающий успех запросов.

Аналитик данных:

  • Проверил качество извлечённых полей на примерах.
  • Настроил трансформации и валидацию перед загрузкой в хранилище.

Частые ошибки и как их избежать

  • Неправильные селекторы — решается инспекцией DOM и использованием более специфичных путей.
  • Отсутствие обработки ошибок сети — добавьте повторные попытки и таймауты.
  • Сохранение необработанных данных — всегда нормализуйте текст и проверяйте атрибуты.

Совместимость и миграция

  • goquery работает с net/html; при переходе на более сложные JS-рендерящие страницы переходите на ChromeDP.
  • При масштабировании переходите с локального хранилища на реляционную или NoSQL БД.

Примеры конфигураций и сниппеты

Настройка http.Client с таймаутом:

client := &http.Client{
    Timeout: 10 * time.Second,
}
resp, err := client.Get(url)

Пример тримминга текста:

raw := selector.Find("td.title").Text()
title := strings.TrimSpace(raw)

Приватность и соответствие регуляциям

Если вы обрабатываете персональные данные, учитывайте требования GDPR и локальные законы. Храните минимально необходимый объём данных и документируйте основания обработки.

Итог и рекомендации

goquery — отличный старт для задач по вытягиванию данных со статичных страниц. Он прост, эффективен и легко интегрируется в приложения на Go. Для динамического контента и больших масштабов рассмотрите ChromeDP или Colly. Всегда начинайте с малого: протестируйте селекторы на статическом HTML, добавьте обработку ошибок и ограничения скорости, затем масштабируйте.

Заметка: документируйте источник данных и частоту обновления — это поможет отслеживать качество и соответствие закону.

Вывод скрейпинга в структуре данных

Ключевые шаги по памяти: запрос → парсинг → селектор → сохранение. Следуйте чеклисту SOP перед запуском на продакшн.

Резюме

  • goquery подходит для статичных сайтов и быстрого прототипирования.
  • Для JS-рендеринга используйте ChromeDP или headless-браузер.
  • Добавляйте таймауты, ретраи, rate-limiting и логирование.
  • Соблюдайте юридические и этические требования при сборе данных.

В следующем проекте начните с простого скрипта на goquery и постепенно вносите улучшения по мере роста требований.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как сменить язык в Tor Browser на ПК и Android
браузер

Как сменить язык в Tor Browser на ПК и Android

Отключить Windows Copilot в Windows 11
Windows

Отключить Windows Copilot в Windows 11

Включение Google Assistant: сделать Android похожим на Pixel
Android.

Включение Google Assistant: сделать Android похожим на Pixel

Dell SupportAssist OS Recovery — что это и как пользоваться
Руководство

Dell SupportAssist OS Recovery — что это и как пользоваться

Удаление файлов и папок через CMD в Windows 10
Windows 10

Удаление файлов и папок через CMD в Windows 10

PS4 Remote Play на Windows — настройка и советы
Гайды

PS4 Remote Play на Windows — настройка и советы