Skip to content

패키지 함수

패키지 수준 함수는 일회성 호출 시나리오에 적합하며, 내부적으로 sync.Pool을 사용하여 Processor 를 재사용하므로 라이프사이클을 수동으로 관리할 필요가 없습니다. 참고: 풀링된 Processor 는 캐시와 감사 보존을 비활성화합니다; 캐시/통계/감사가 필요하면 html.New로 전용 Processor 를 생성하세요.

내부 메커니즘

풀링 설계

패키지 함수는 내부적으로 sync.Pool을 유지하여, 호출 사이에 Processor 인스턴스를 재사용하며 반복 할당을 피합니다. 핵심 구현 세부 사항:

  • 풀링 설정은 캐시 비활성화: 풀용 설정(poolCfg)은 DefaultConfig()를 기반으로 하지만, 캐시 관련 세 필드를 명시적으로 0으로 설정합니다 — MaxCacheEntries=0, CacheTTL=0, CacheCleanup=0. 따라서 패키지 함수는 캐시를 활용할 수 없으며, 매번 전체 처리를 수행합니다. 이렇게 설계된 이유는 풀링된 Processor 가 반납될 때마다 캐시를 비우기 때문에, 캐시를 켜봤자 해시와 map 쓰기 비용만 들 뿐 절대 적중하지 않기 때문입니다.
  • 반납 시 상태 재설정: 매 호출 종료 시 Processor 를 반납하기 전에 ResetStatistics, audit.Wait(), ClearAuditLog, ClearCache를 차례로 실행하여, 호출 간의 통계/감사/캐시 상태 누출을 방지합니다.
  • 이미 닫힌 Processor 는 반납하지 않음: Processor 가 사용 중에 닫힌 경우 (오용), 반납 로직은 이를 풀에 넣지 않고 직접 폐기합니다 (sync.PoolPut 누락을 허용하며, 다음 Getpool.New가 재구성합니다).
  • panic 안전망: pool.New는 라이브러리 불변 조건이 깨졌을 때만 panic 합니다 (poolCfgDefaultConfig()에서 파생되어 생성 시점에 합법적); 이 panic 은 getPooledProcessorSafe에서 포착되어 ErrInternalPanic으로 래핑되어 반환되며, 공개 API 로는 유출되지 않습니다.

설정 매개변수 해석

모든 패키지 함수의 cfg ...Config는 선택적 가변 인자로, 내부 resolveConfig가 해석합니다:

전달 인자동작풀링 사용 여부
미전달DefaultConfig() 사용예(pooled=true)
1 개 전달해당 Config 사용아니오(pooled=false)
≥2 개 전달ErrMultipleConfigs 반환

핵심 차이

커스텀 Config를 전달하면 sync.Pool을 거치지 않습니다 — 풀은 DefaultConfig() 기반의 Processor 만 저장하며, 설정이 다른 인스턴스를 안전하게 재사용할 수 없습니다. 이 경우 매 호출마다 임시 Processor 를 New로 생성하고, 사용 후 즉시 Close합니다. 고빈도 호출에서 커스텀 설정을 재사용하려면 Processor를 직접 생성하세요.

콘텐츠 추출

Extract

HTML 바이트에서 콘텐츠를 추출하여 완전한 Result를 반환합니다.

go
func Extract(htmlBytes []byte, cfg ...Config) (*Result, error)

매개변수:

매개변수타입설명
htmlBytes[]byteHTML 콘텐츠
cfg...Config선택적 설정, 최대 1 개

예시:

go
result, err := html.Extract(data)
if err != nil {
    log.Fatal(err)
}
fmt.Println(result.Title, result.Text)

완전히 실행 가능한 예시 (필드 접근과 오류 처리 시연):

go
package main

import (
	"fmt"
	"log"

	"github.com/cybergodev/html"
)

func main() {
	data := []byte(`<html><head><title>예제 페이지</title></head>
<body><h1>환영합니다</h1><p>본문 내용<a href="https://example.com">링크</a>.</p></body></html>`)

	// Config 미전달, 풀링 경로 사용
	result, err := html.Extract(data)
	if err != nil {
		log.Fatalf("추출 실패: %v", err)
	}

	fmt.Println("제목:", result.Title)
	fmt.Println("단어 수:", result.WordCount)
	fmt.Println("링크 수:", len(result.Links))
	// 출력:
	// 제목: 예제 페이지
	// 단어 수: 4
	// 링크 수: 1
}

오류 반환: ExtractProcessor.Extract와 동일한 오류를 반환하며, 추가로 다음을 반환할 수 있습니다:

오류조건
ErrMultipleConfigs2 개 이상의 Config 전달
ErrInvalidConfig(*ConfigError로 래핑)전달된 Config 검증 실패 (예: MaxInputSize<=0)

ExtractFromFile

HTML 파일에서 콘텐츠를 추출합니다.

go
func ExtractFromFile(filePath string, cfg ...Config) (*Result, error)

오류 반환: Extract의 오류 외에도, 파일 접근 시 *FileError를 반환할 수 있으며, ErrFileNotFound, ErrInvalidFilePath 또는 경로 순회 거부를 래핑합니다 (보안 방어AllowedBaseDir 참조).

텍스트 추출

ExtractText

순수 텍스트 콘텐츠만 추출합니다.

go
func ExtractText(htmlBytes []byte, cfg ...Config) (string, error)

ExtractTextFromFile

파일에서 순수 텍스트를 추출합니다.

go
func ExtractTextFromFile(filePath string, cfg ...Config) (string, error)

컨텍스트 버전

모든 함수는 context.Context가 포함된 버전을 지원하여 취소 및 타임아웃 제어에 사용합니다:

함수시그니처
ExtractWithContext(ctx context.Context, htmlBytes []byte, cfg ...Config) (*Result, error)
ExtractFromFileWithContext(ctx context.Context, filePath string, cfg ...Config) (*Result, error)
ExtractTextWithContext(ctx context.Context, htmlBytes []byte, cfg ...Config) (string, error)
ExtractTextFromFileWithContext(ctx context.Context, filePath string, cfg ...Config) (string, error)
go
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

result, err := html.ExtractWithContext(ctx, data)

출력 형식

함수시그니처설명
ExtractToMarkdown(htmlBytes []byte, cfg ...Config) (string, error)HTML → Markdown
ExtractToMarkdownFromFile(filePath string, cfg ...Config) (string, error)파일 → Markdown
ExtractToMarkdownWithContext(ctx context.Context, htmlBytes []byte, cfg ...Config) (string, error)컨텍스트 포함
ExtractToMarkdownFromFileWithContext(ctx context.Context, filePath string, cfg ...Config) (string, error)파일 + 컨텍스트
ExtractToJSON(htmlBytes []byte, cfg ...Config) ([]byte, error)HTML → JSON
ExtractToJSONFromFile(filePath string, cfg ...Config) ([]byte, error)파일 → JSON
ExtractToJSONWithContext(ctx context.Context, htmlBytes []byte, cfg ...Config) ([]byte, error)컨텍스트 포함
ExtractToJSONFromFileWithContext(ctx context.Context, filePath string, cfg ...Config) ([]byte, error)파일 + 컨텍스트

자세한 사용법과 예시는 출력 형식을 참조하세요.

링크 추출

함수시그니처설명
ExtractAllLinks(htmlBytes []byte, cfg ...Config) ([]LinkResource, error)모든 링크 추출
ExtractAllLinksFromFile(filePath string, cfg ...Config) ([]LinkResource, error)파일에서 링크 추출
ExtractAllLinksWithContext(ctx context.Context, htmlBytes []byte, cfg ...Config) ([]LinkResource, error)컨텍스트 포함
ExtractAllLinksFromFileWithContext(ctx context.Context, filePath string, cfg ...Config) ([]LinkResource, error)파일 + 컨텍스트

자세한 사용법과 예시는 링크 추출을 참조하세요.

배치 처리

함수시그니처설명
ExtractBatch(htmlContents [][]byte, cfg ...Config) *BatchResult배치 추출
ExtractBatchWithContext(ctx context.Context, htmlContents [][]byte, cfg ...Config) *BatchResult컨텍스트 포함
ExtractBatchFiles(filePaths []string, cfg ...Config) *BatchResult배치 파일 추출
ExtractBatchFilesWithContext(ctx context.Context, filePaths []string, cfg ...Config) *BatchResult파일 + 컨텍스트

자세한 사용법과 예시는 배치 처리를 참조하세요.

패키지 함수 vs Processor

둘 다 내부적으로 Processor를 호출하지만, 리소스 재사용과 상태 보존에서 차이가 뚜렷합니다:

차원패키지 함수Processor
캐시없음(풀링 설정 MaxCacheEntries=0)있음 (적중 시 딥카피 반환)
통계매번 재설정 (반납 시 ResetStatistics)누적, 언제든 GetStatistics 가능
감사 로그매번 비움 (반납 시 ClearAuditLog)누적, GetAuditLog로 조회 가능
커스텀 Config매번 임시 Processor 생성+파괴동일 인스턴스 재사용
라이프사이클자동 관리 (풀/임시 인스턴스)수동 defer Close() 필요
적용 시나리오일회성 호출, 스크립트, 저빈도 요청고빈도 호출, 장기 실행 서비스, 캐시 필요

선택 조언

단일 추출이나 간헐적 호출에는 패키지 함수가 가장 편리합니다; 루프, HTTP handler, 배치 처리에서 반복 추출하려면 장기 생존하는 Processor를 생성하고 재사용하면, 캐시를 활용해 오버헤드를 크게 줄일 수 있습니다.