Как парсить сайт с помощью Go и goquery

118
технологии 34.webp

Последнее обновление 09.01.2023 — Василий Иванов

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

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

Веб-скраперы пригодятся для получения данных с веб-сайтов, которые не предоставляют API. Они популярны в таких областях, как наука о данных, кибербезопасность, разработка интерфейсов и серверных частей.

Веб-скрейпинг в Go

В Go есть различные пакеты веб-скрейпинга. Популярные включают goquery, Colly и ChromeDP.

ChromeDP — это пакет веб-драйверов, похожий на селен. Он поддерживает протокол инструментов разработчика Chrome в Go без зависимостей.

По теме:  Что такое SMS на iPhone?

Colly — это библиотека для парсинга веб-страниц, созданная с использованием goquery. Но goquery — более быстрый вариант для парсинга веб-сайтов в Go.

Что такое гокери?

Библиотека CSS, jQuery, помогла вдохновить goquery. Это библиотека Go, основанная на пакете net/html, который реализует совместимый с HTML5 токенизатор и парсер. Он также использует пакет Cascadia, который реализует селекторы CSS для использования с парсером, предоставляемым net/html.

Установка goquery

Запустите приведенную ниже команду в своем терминале, чтобы установить goquery. Если вы столкнулись с какими-либо ошибками, попробуйте обновить версию Go.

go get github.com/PuerkitoBio/goquery

Процесс парсинга веб-страниц

Весь процесс парсинга можно разделить на три более мелкие задачи:

  1. Выполнение HTTP-запросов.
  2. Использование селекторов и локаторов для получения необходимых данных.
  3. Сохранение данных в базе данных или структурах данных для дальнейшей обработки.

Выполнение HTTP-запросов в Go

Вы можете отправлять HTTP-запросы с помощью пакета net/http, который входит в стандартную библиотеку Go.

package main

import "net/http"
import "log"
import "fmt"

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 возвращает тело ответа и ошибку. response.StatusCode — это код состояния запроса-ответа.

При выполнении HTTP-запросов, если код состояния ответа равен 200, вы можете приступить к очистке веб-сайта.

Получение необходимых данных с помощью goquery

Получение HTML-кода веб-сайта

Во-первых, вам нужно проанализировать простой HTML-код из ответа (response.body), чтобы получить полный объект документа, представляющий веб-страницу:

document, err := goquery.NewDocumentFromReader(response.Body)

if err != nil {
log.Fatalln(err)
}

Теперь вы можете использовать объект документа для доступа к структуре и содержимому веб-страницы.

Выбор необходимых элементов из HTML

Вам нужно будет проверить веб-страницу, чтобы проверить структуру данных, которые необходимо извлечь. Это поможет вам создать селектор для доступа к нему.

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

Метод Find использует селектор CSS для поиска элемента, содержащего необходимые данные:

document.Find("tr.athing")

Приведенный выше код возвращает только первый элемент HTML, соответствующий селектору, или пустой список, если совпадения не было вообще.

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

В большинстве случаев вам потребуется получить все HTML-элементы, соответствующие вашему селектору.

Вы можете выбрать все соответствующие элементы в HTML, используя метод Every значения, которое возвращает Find(). Метод Each принимает функцию с двумя параметрами: индексом и селектором типа *goquery.Selection.

document.Find("tr.athing").Each(func(index int, selector *goquery.Selection) {
/* Process selector here */
})

В теле функции вы можете выбрать нужные данные из HTML. В этом случае вам нужны ссылки и заголовки каждого поста на странице. Используйте метод Find параметра 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")
})

Приведенный выше код вызывает метод Text результата selector.Find для извлечения содержимого ячейки таблицы. Для выбора атрибутов, таких как URL-адреса ссылок и изображений, необходимо использовать метод Attr. Этот метод также возвращает значение, указывающее, существует ли вообще атрибут.

Процесс такой же, как и при выборе любых элементов и атрибутов на веб-странице.

Метод Find очень мощный, он позволяет выполнять широкий спектр операций по выбору и местонахождению HTML-элементов. Вы можете изучить их в документации goquery.

Сохранение очищенных данных

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

Создайте структуру с полями title и link, а также часть структур для хранения типа структуры.

type Information struct {
link string
title string
}
info := make([]Information, 0)

После создания структуры и среза в теле функции метода документа заполните срез в функции, которую вы передаете методу Find. Используйте тип struct для создания экземпляров новых структур данных, каждая из которых содержит один результат.

info = append(info, Information{
title: title,
link: link,
})

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

Печать фрагмента показывает, что вы успешно очистили веб-сайт и заполнили фрагмент.

fmt.Println(info)

Собранные данные разумно сохранять в локальном кеше, чтобы не нагружать сервер веб-страницы больше, чем нужно. Это не только уменьшит трафик, но и ускорит ваше приложение, поскольку оно быстрее извлекает локальные данные, чем делать запросы и очищать веб-сайты.

В Go есть множество пакетов баз данных, которые можно использовать для сохранения данных. Пакет database/sql поддерживает базы данных SQL. Существуют также клиенты базы данных NoSQL, такие как драйвер MongoDB Go, и бессерверные базы данных, такие как FaunaDB, использующие драйвер FaunaDB.

Суть парсинга веб-страниц в Go

Если вы пытаетесь собрать данные с веб-сайта, goquery — отличное место для начала. Но это мощный пакет, который может делать больше, чем просто просмотр веб-страниц. Подробнее о его функционале вы можете узнать в официальной документации проекта.

Веб-скрапинг — важный навык в различных областях технологий, и он пригодится во многих ваших проектах.