Часто задаваемые вопросы
В чём разница между функциями пакета и Processor?
Функции пакета (например, html.Extract) внутри используют sync.Pool для повторного использования Processor и подходят для редких, однократных вызовов. После каждого вызова Processor возвращается в пул.
Processor (например, p := html.New()) подходит для высокочастотных вызовов, повторно используя кэш и внутренние ресурсы. Также поддерживает сбор статистики и журнал аудита.
// Редкие вызовы: функции пакета
result, _ := html.Extract(data)
// Высокочастотные вызовы: Processor
p, _ := html.New(html.DefaultConfig())
defer p.Close()
for _, page := range pages {
p.Extract(page)
}Как обрабатывать проблемы с кодировкой?
Библиотека HTML автоматически определяет 15+ кодировок (UTF-8, GBK, Shift_JIS, Windows-1252 и др.), обычно ручное указание не требуется.
Если необходимо принудительно указать кодировку:
cfg := html.DefaultConfig()
cfg.Encoding = "gbk"Каков лимит размера ввода?
По умолчанию максимум 50 МБ (DefaultMaxInputSize = 52428800). Можно изменить через конфигурацию:
cfg.MaxInputSize = 10 * 1024 * 1024 // 10 МБКак получить вывод в формате Markdown?
md, err := html.ExtractToMarkdown(data)Или с использованием Processor:
p, _ := html.New()
md, _ := p.ExtractToMarkdown(data)Сколько элементов можно обработать в пакетном режиме?
Максимум 10 000 элементов за один вызов. Для больших наборов данных обрабатывайте пакетами.
Почему извлечённый текст пуст?
Возможные причины:
- Проблема структуры HTML — содержимое находится внутри тегов
<script>или<style> - Пустое содержимое после санирования — если основной текст существует только в тегах, удаляемых при санировании (например
<iframe>,<object>), результат может быть пустым; для доверенного ввода можно временно установитьEnableSanitization = falseдля диагностики - Пустой ввод — проверьте, что входной массив байтов не пуст (пустое содержимое возвращает пустой
Result) - Распознавание статьи — попробуйте отключить
ExtractArticleи проверить, извлекается ли содержимое
Различайте ошибки и пустые результаты
Превышение глубины вложенности DOM относительно MaxDepth даёт не пустой текст, а ошибку ErrMaxDepthExceeded. Если вызов возвращает error, сначала определите тип ошибки через errors.Is, а не проверяйте, пуст ли текст.
cfg := html.DefaultConfig()
cfg.ExtractArticle = false // Отключить распознавание статьиКак отслеживать статистику обработки?
p, _ := html.New(html.DefaultConfig())
defer p.Close()
// После обработки некоторого контента
stats := p.GetStatistics()
fmt.Printf("Обработано: %d\n", stats.TotalProcessed)
fmt.Printf("Попаданий в кэш: %d\n", stats.CacheHits)
fmt.Printf("Среднее время: %v\n", stats.AverageProcessTime)
fmt.Printf("Ошибок: %d\n", stats.ErrorCount)Как включить аудит?
cfg := html.DefaultConfig()
cfg.Audit = html.DefaultAuditConfig()
cfg.Audit.Enabled = true
cfg.Audit.Sink = html.NewLoggerAuditSink()Подробнее в Система аудита.
Безопасны ли пути к файлам?
FileError автоматически усекает полный путь, предотвращая утечку серверных путей в сообщениях об ошибках:
var fileErr *html.FileError
if errors.As(err, &fileErr) {
fmt.Println(fileErr.SafePath()) // Только имя файла, без полного пути
}Как реализовать пользовательский скоринг контента?
Реализуйте интерфейс Scorer:
type MyScorer struct{}
func (s *MyScorer) Score(node html.ContentNode) int {
// Пользовательская логика скоринга
return 0
}
func (s *MyScorer) ShouldRemove(node html.ContentNode) bool {
// Пользовательская логика удаления
return false
}
cfg := html.DefaultConfig()
cfg.Scorer = &MyScorer{}Подробнее в Определение интерфейсов.