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")