HTMLHeaderTextSplitter

텍스트 분할

효율적인 문서 청킹을 위한 다양한 텍스트 분할 전략을 다룬다.

AI
RAG
LangChain
저자

Kwangmin Kim

공개

2024년 12월 31일

MarkdownHeaderTextSplitter와 개념적으로 유사한 HTMLHeaderTextSplitter는 텍스트를 요소 수준에서 분할하고 각 헤더에 대한 메타데이터를 추가하는 “구조 인식” 청크 생성기입니다.

이는 각 청크와 “관련된” 메타데이터를 추가합니다.

HTMLHeaderTextSplitter는 요소별로 청크를 반환하거나 동일한 메타데이터를 가진 요소를 결합할 수 있으며

1 HTML 문자열을 사용하는 경우

  • headers_to_split_on 리스트에 분할 기준이 되는 헤더 태그와 해당 헤더의 이름을 튜플 형태로 지정합니다.
  • HTMLHeaderTextSplitter 객체를 생성하면서 headers_to_split_on 매개변수에 분할 기준 헤더 리스트를 전달합니다.
from langchain_text_splitters import HTMLHeaderTextSplitter

html_string = """
<!DOCTYPE html>
<html>
<body>
    <div>
        <h1>헤더1</h1>
        <p>헤더1 에 포함된 본문</p>
        <div>
            <h2>헤더2-1 제목</h2>
            <p>헤더2-1 에 포함된 본문</p>
            <h3>헤더3-1 제목</h3>
            <p>헤더3-1 에 포함된 본문</p>
            <h3>헤더3-2 제목</h3>
            <p>헤더3-2 에 포함된 본문</p>
        </div>
        <div>
            <h2>헤더2-2 제목2</h2>
            <p>헤더2-2 에 포함된 본문</p>
        </div>
        <br>
        <p>마지막 내용</p>
    </div>
</body>
</html>
"""

headers_to_split_on = [
    ("h1", "Header 1"),  # 분할할 헤더 태그와 해당 헤더의 이름을 지정합니다.
    ("h2", "Header 2"),
    ("h3", "Header 3"),
]

# 지정된 헤더를 기준으로 HTML 텍스트를 분할하는 HTMLHeaderTextSplitter 객체를 생성합니다.
html_splitter = HTMLHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
# HTML 문자열을 분할하여 결과를 html_header_splits 변수에 저장합니다.
html_header_splits = html_splitter.split_text(html_string)
# 분할된 결과를 출력합니다.
for header in html_header_splits:
    print(f"{header.page_content}")
    print(f"{header.metadata}", end="\n=====================\n")

2 다른 splitter와 파이프라인으로 연결하고, 웹 URL에서 HTML을 로드하는 경우입니다.

이 예시에서는 웹 URL로부터 HTML 콘텐츠를 로드한 후, 이를 다른 splitter와 파이프라인으로 연결하여 처리하는 과정입니다.

from langchain_text_splitters import RecursiveCharacterTextSplitter

url = "https://plato.stanford.edu/entries/goedel/"  # 분할할 텍스트의 URL을 지정합니다.

headers_to_split_on = [  # 분할할 HTML 헤더 태그와 해당 헤더의 이름을 지정합니다.
    ("h1", "Header 1"),
    ("h2", "Header 2"),
    ("h3", "Header 3"),
    ("h4", "Header 4"),
]

# HTML 헤더를 기준으로 텍스트를 분할하는 HTMLHeaderTextSplitter 객체를 생성합니다.
html_splitter = HTMLHeaderTextSplitter(headers_to_split_on=headers_to_split_on)

# URL에서 텍스트를 가져와 HTML 헤더를 기준으로 분할합니다.
html_header_splits = html_splitter.split_text_from_url(url)

chunk_size = 500  # 텍스트를 분할할 청크의 크기를 지정합니다.
chunk_overlap = 30  # 분할된 청크 간의 중복되는 문자 수를 지정합니다.
text_splitter = RecursiveCharacterTextSplitter(  # 텍스트를 재귀적으로 분할하는 RecursiveCharacterTextSplitter 객체를 생성합니다.
    chunk_size=chunk_size, chunk_overlap=chunk_overlap
)

# HTML 헤더로 분할된 텍스트를 다시 청크 크기에 맞게 분할합니다.
splits = text_splitter.split_documents(html_header_splits)

# 분할된 텍스트 중 80번째부터 85번째까지의 청크를 출력합니다.
for header in splits[80:85]:
    print(f"{header.page_content}")
    print(f"{header.metadata}", end="\n=====================\n")

3 한계

HTMLHeaderTextSplitter는 HTML 문서 간의 구조적 차이를 처리하려고 시도하지만, 때로는 특정 헤더를 누락할 수 있습니다.

예를 들어, 이 알고리즘은 헤더가 항상 관련 텍스트보다 “위”에 있는 노드, 즉 이전 형제 노드, 조상 노드 및 이들의 조합에 위치한다고 가정합니다.

다음 뉴스 기사(이 문서 작성 시점 기준)에서는 최상위 헤드라인의 텍스트가 “h1”으로 태그되어 있지만, 우리가 예상하는 텍스트 요소와는 별개의 하위 트리 에 있는 것을 볼 수 있습니다.

따라서 “h1” 요소와 관련 텍스트는 청크 메타데이터에 나타나지 않지만, 해당되는 경우 “h2”와 관련 텍스트는 볼 수 있습니다.

# 분할할 HTML 페이지의 URL을 지정합니다.
url = "https://www.cnn.com/2023/09/25/weather/el-nino-winter-us-climate/index.html"

headers_to_split_on = [
    ("h1", "Header 1"),  # 분할할 헤더 태그와 해당 헤더의 이름을 지정합니다.
    ("h2", "Header 2"),  # 분할할 헤더 태그와 해당 헤더의 이름을 지정합니다.
]

# 지정된 헤더를 기준으로 HTML 텍스트를 분할하는 HTMLHeaderTextSplitter 객체를 생성합니다.
html_splitter = HTMLHeaderTextSplitter(headers_to_split_on=headers_to_split_on)

# 지정된 URL의 HTML 페이지를 분할하여 결과를 html_header_splits 변수에 저장합니다.
html_header_splits = html_splitter.split_text_from_url(url)

# 분할된 결과를 출력합니다.
for header in html_header_splits:
    print(f"{header.page_content[:100]}")
    print(f"{header.metadata}", end="\n=====================\n")

Subscribe

Enjoy this blog? Get notified of new posts by email: