Введение: Почему 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