Парсинг и скрапинг данных на Go: Мощь, Скорость и Простота

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Почему Go — ваш новый лучший друг в мире парсинга

Представьте ситуацию: вам нужно собрать информацию с сотен веб-страниц, обработать её и сохранить в структурированном виде. Python с его BeautifulSoup и Scrapy кажется очевидным выбором. Но что, если я скажу вам, что есть язык, который делает это быстрее, легче и с меньшим потреблением памяти? Встречайте — парсинг и скрапинг данных на Go.

Go (или Golang) — это не просто модный язык от Google. Это инструмент, который превращает написание парсеров из рутины в удовольствие. Благодаря встроенной поддержке конкурентности (горутины), вы можете параллельно обрабатывать десятки страниц, не беспокоясь о блокировках. А его строгая типизация и скорость компиляции делают код надёжным и производительным.

В этой статье мы не будем скучно перечислять функции. Мы напишем реальный парсер на Go, разберём ключевые библиотеки и покажем, как создавать скраперы, которые выдерживают нагрузку. Если вы хотите научиться парсить сайты на Go быстро и эффективно — вы по адресу.

Что такое парсинг и скрапинг, и зачем вам Go?

Давайте сразу расставим точки над i. Веб-скрапинг (scraping) — это процесс извлечения данных с веб-страниц. Парсинг (parsing) — это анализ полученного HTML или JSON для извлечения нужной информации. Вместе они образуют мощный тандем для сбора данных.

Почему стоит выбрать парсинг на Go вместо привычного Python?

  • Скорость выполнения: Go компилируется в бинарник, который работает в разы быстрее интерпретируемого Python. Это критично при обработке миллионов страниц.
  • Экономия памяти: Горутины (легковесные потоки) потребляют всего несколько килобайт, в отличие от потоков ОС. Вы можете запустить тысячи параллельных запросов без риска утечки памяти.
  • Простота деплоя: Скомпилированный бинарник не требует установки зависимостей. Закинули на сервер — и парсер готов к работе.
  • Встроенный HTTP-клиент: Стандартная библиотека Go уже содержит всё необходимое для работы с сетью. Никаких лишних зависимостей.

Итак, если вам нужен парсер на Go, который будет работать как часы — вы выбрали правильный язык.

Инструментарий: Colly и Goquery — ваш джентльменский набор

Прежде чем писать код, давайте познакомимся с главными инструментами. Для веб-скрапинга Golang есть две «золотые» библиотеки:

Colly — король асинхронного скрапинга

Colly — это фреймворк для скрапинга, который вобрал в себя лучшие практики. Он поддерживает параллельные запросы, управление куками, автоматическое ожидание между запросами (чтобы вас не забанили) и даже кэширование. Colly работает поверх Goquery для парсинга HTML.

Goquery — jQuery для Go

Goquery — это библиотека, которая позволяет выбирать элементы HTML с помощью CSS-селекторов, точно так же, как вы делаете это в jQuery. Если вы когда-нибудь писали $(".my-class").text() в JavaScript, то Goquery покажется вам родным.

Установка проста:

go get github.com/gocolly/colly/v2
go get github.com/PuerkitoBio/goquery

Теперь у нас есть всё для создания парсера на Go.

Пишем реальный парсер: собираем заголовки новостей

Для примера давайте напишем скрапер, который собирает заголовки новостей с сайта-агрегатора (например, Hacker News или любой другой новостной ленты). Мы будем парсить HTML и выводить результаты в консоль.

Создайте файл main.go и напишите следующий код:

package main

import (
	"fmt"
	"log"

	"github.com/gocolly/colly/v2"
)

func main() {
	// Создаём нового коллектора
	c := colly.NewCollector(
		colly.AllowedDomains("news.ycombinator.com"),
	)

	// Ограничиваем количество параллельных запросов
	c.Limit(&colly.LimitRule{
		DomainGlob:  "*",
		Parallelism: 2,
		Delay:       1 * time.Second,
	})

	// Обработчик для каждого найденного элемента
	c.OnHTML("span.titleline > a", func(e *colly.HTMLElement) {
		title := e.Text
		link := e.Attr("href")
		fmt.Printf("Заголовок: %s\nСсылка: %s\n\n", title, link)
	})

	// Логирование запросов
	c.OnRequest(func(r *colly.Request) {
		log.Println("Посещаем:", r.URL.String())
	})

	// Стартуем
	err := c.Visit("https://news.ycombinator.com/")
	if err != nil {
		log.Fatal(err)
	}

	// Ждём завершения всех горутин
	c.Wait()
}

Разбор кода:

  • colly.NewCollector() — создаёт объект, который будет выполнять запросы.
  • AllowedDomains — защита от случайного ухода на другие сайты.
  • Limit — настройка параллелизма и задержки. Это важно, чтобы не нагружать сервер.
  • OnHTML — регистрирует callback для каждого элемента, соответствующего CSS-селектору span.titleline > a (все ссылки внутри спана с классом titleline).
  • Visit — начинает обход страницы.

Запустите программу командой go run main.go. Вы увидите, как в консоль выводятся заголовки и ссылки. Это базовый, но уже рабочий парсинг на Go.

Продвинутый парсинг: извлекаем данные в структуры

Собирать заголовки в консоль — весело, но бесполезно. Давайте научимся сохранять данные в структуры и записывать их в JSON. Это превратит наш скрапер в полноценный инструмент сбора данных на Go.

Модифицируем код:

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/gocolly/colly/v2"
)

// Структура для хранения новости
type NewsItem struct {
	Title string `json:"title"`
	Link  string `json:"link"`
}

func main() {
	var news []NewsItem

	c := colly.NewCollector(
		colly.AllowedDomains("news.ycombinator.com"),
	)

	c.Limit(&colly.LimitRule{
		DomainGlob:  "*",
		Parallelism: 2,
		Delay:       1 * time.Second,
	})

	c.OnHTML("span.titleline > a                

Блоги

Рекомендаций по книгам