---
sidebar_label: "Извлечение контента на практике"
title: "Извлечение контента - CyberGo html | на практике"
description: "Извлечение контента CyberGo html на практике: процесс, интеллектуальное распознавание статей, поля Result, пользовательский Scorer и кодировки."
sidebar_position: 1
---

# Извлечение контента на практике

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

## Обзор процесса извлечения

При вызове `Extract` библиотека выполняет следующие шаги:

```text
Ввод HTML → валидация ввода → определение кодировки (автоконвертация в UTF-8) → разбор DOM → проверка глубины
    → безопасное санирование (опц.) → распознавание статьи (опц.) → извлечение содержимого → форматирование → возврат Result
```

Проверка глубины выполняется **до** санирования: сначала итеративно проверяется глубина DOM (чтобы избежать переполнения стека из-за рекурсивного обхода), а затем выполняется безопасное санирование разобранного DOM-дерева. Обе операции работают с разобранным деревом узлов, поэтому разбор DOM всегда предшествует им обеим.

Каждый шаг можно настроить через [конфигурацию](../../api-reference/core/config).

## Базовое извлечение текста

Простейшее использование — извлечение контента из байтов HTML:

```go
package main

import (
    "fmt"
    "log"

    "github.com/cybergodev/html"
)

func main() {
    data := []byte(`<html>
        <head><title>Руководство по Go</title></head>
        <body>
            <article>
                <h1>Введение в Go</h1>
                <p>Go — это статически типизированный компилируемый язык со встроенной поддержкой параллелизма.</p>
                <p>Он отличается быстрой компиляцией, простотой развёртывания и подходит для создания высокопроизводительных сервисов.</p>
                <img src="gopher.png" alt="Талисман Gopher" />
                <a href="https://go.dev">Официальный сайт Go</a>
            </article>
        </body>
    </html>`)

    result, err := html.Extract(data)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Заголовок:", result.Title)
    // Заголовок: Руководство по Go

    fmt.Println("Текст:", result.Text)
    // Текст: Введение в Go
    //       Go — это статически типизированный компилируемый язык со встроенной поддержкой параллелизма.
    //       Он отличается быстрой компиляцией, простотой развёртывания и подходит для создания высокопроизводительных сервисов.
    //       Официальный сайт Go

    fmt.Println("Слов:", result.WordCount)
    // Слов: 7

    fmt.Println("Время чтения:", result.ReadingTime)
    // Время чтения: 2.1с (при расчёте 200 слов/мин)

    fmt.Println("Изображений:", len(result.Images))
    // Изображений: 1

    fmt.Println("Ссылок:", len(result.Links))
    // Ссылок: 1
}
```

## Понимание результата извлечения

`Result` содержит следующие поля:

| Поле | Тип | Описание |
|------|------|------|
| `Title` | `string` | Заголовок страницы, приоритет: `<title>`, затем `<h1>`, `<h2>` |
| `Text` | `string` | Основной текст (очищенный, без тегов и лишних пробелов) |
| `Images` | `[]ImageInfo` | Список извлечённых изображений |
| `Links` | `[]LinkInfo` | Список извлечённых ссылок |
| `Videos` | `[]VideoInfo` | Список извлечённых видео |
| `Audios` | `[]AudioInfo` | Список извлечённых аудио |
| `WordCount` | `int` | Количество слов в тексте |
| `ReadingTime` | `time.Duration` | Расчётное время чтения (200 слов/мин) |
| `ProcessingTime` | `time.Duration` | Время обработки |

## Извлечение из файла

Для обработки локальных HTML-файлов используйте `ExtractFromFile`:

```go
result, err := html.ExtractFromFile("article.html")
if err != nil {
    log.Fatal(err)
}
fmt.Println("Заголовок:", result.Title)
```

Файловые операции включают встроенные проверки безопасности:
- Автоматическое обнаружение атак с обходом пути (например, `../../../etc/passwd`)
- Размер файла ограничен `MaxInputSize`
- Сообщения об ошибках скрывают полный путь через `SafePath()`

## Алгоритм распознавания статей

Когда `ExtractArticle` равен `true` (по умолчанию), библиотека автоматически определяет «основную область контента» на странице.

### Принцип работы

1. **Оценка кандидатов**: обход дерева DOM, вычисление оценки релевантности контента для каждого элемента
2. **Выбор лучшего кандидата**: выбор узла с наивысшей оценкой в качестве контейнера статьи
3. **Механизм отката**: если подходящий кандидат не найден, откат к узлу `<body>`

:::tip Подходящие сценарии
Распознавание статей лучше всего подходит для новостных сайтов, блогов, документации и других страниц с чётко выраженной «областью основного контента». Для навигационных страниц и страниц-списков может быть затруднено точное определение основного текста.
:::

### Пользовательский скоринг

Настройка логики скоринга через реализацию интерфейса `Scorer`:

```go
type myScorer struct{}

func (s myScorer) Score(node html.ContentNode) int {
    // Возвращаем оценку на основе характеристик узла
    class := node.AttrValue("class")
    if strings.Contains(class, "article") || strings.Contains(class, "post") {
        return 100
    }
    if strings.Contains(class, "sidebar") || strings.Contains(class, "comment") {
        return -50
    }
    return 0
}

func (s myScorer) ShouldRemove(node html.ContentNode) bool {
    // Возвращаем true для удаления узла
    return node.Data() == "nav" || node.Data() == "footer"
}
```

:::tip Примечание
Функция `strings.Contains` в этом примере из стандартного пакета `strings`. Полный работоспособный пример см. в [Тестирование и пользовательские расширения](../integration/testing-custom).
:::

## Извлечение только текста

Когда нужен только текст без изображений, ссылок и других метаданных:

```go
text, err := html.ExtractText(data)
if err != nil {
    log.Fatal(err)
}
fmt.Println(text)
```

Это особенно полезно для анализа текста, построения поисковых индексов и других сценариев.

## Обработка не-UTF-8 кодировок

Библиотека автоматически определяет 15+ кодировок (включая UTF-8, GBK, Shift_JIS, Windows-1252 и др.) и автоматически конвертирует в UTF-8.

```go
// Автоматическое определение кодировки
result, err := html.Extract(gbkEncodedData)

// Ручное указание кодировки
cfg := html.DefaultConfig()
cfg.Encoding = "gbk"
result, err = html.Extract(gbkEncodedData, cfg)
```

## Контекст и тайм-аут

Для больших файлов или HTML из ненадёжных источников рекомендуется использовать версии с контекстом:

```go
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

result, err := html.ExtractWithContext(ctx, data)
if errors.Is(err, html.ErrProcessingTimeout) {
    log.Println("Тайм-аут обработки")
}
```

## Следующие шаги

- [Выбор формата вывода](./output-formats) - Выбор подходящего формата для вашего сценария
- [Повторное использование Processor и кэш](../advanced-patterns/processor-cache) - Оптимизация производительности при высокочастотных вызовах
- [Справочник API: Функции пакета](../../api-reference/core/functions) - Полные сигнатуры функций
