본문 바로가기
# 연구실

한글 hwp 파일을 텍스트 txt 로 긁어와서 데이터로 활용하기

by lakedaimong 2022. 6. 23.

웹자료 뿐만 아니라 문서로 만들어진 자료를 데이터로 활용해야 할 때가 있습니다. 우리나라에서는 공공기관은 당연하고 기업에서 '한글.hwp' 을 많이 사용하는데요. 특히 표로된 서식을 많이 사용하기 때문에 한글 자체에서 데이터를 긁어 오기에는 한계가 있습니다. 그래서 한글 hwp 파일을 텍스트 txt 파일로 긁어와서 데이터로 활용할 수 있도록 해보겠습니다.

 

파이썬 python을 이용해서 한글파일의 텍스트를 긁어오는 방식은 pyhwp 또는 olefile 패키지를 이용하는 방법이 있습니다. 시험해본 결과 표로된 한글 문서에서 텍스트를 가져오는데 pyhwp는 잘 작동되지 않는 것으로 확인했습니다. 저는 olefile 패키지를 활용한 방법을 안내드리겠습니다.

import olefile

ole = olefile.OleFileIO('./file.hwp')
encoded_text = ole.openstream('PrvText').read()
decoded_text = encoded_text.decode('UTF-16')

print(decoded_text)

구글링을 해보면 위와같은 방법으로 설명된 포스팅이 많은데 실제로 해보시면 2페이지 이상 텍스트를 긁어오지 못한다는 것을 알 수 있을겁니다. 저도 이것때문에 엄청 고민했는데요. 아마 PrvText 라는게 미리보기를 뜻하는게 아닐까? 했는데 역시나 문서파일의 미리보기 영역만 가져오는 거라 2페이지 이상의 텍스트 데이터를 긁어오지 못하는 것이었습니다.

그렇게 헤매던 중 고수의 자료를 발견했습니다.

import olefile
import zlib
import struct

def get_hwp_text(filename):
    f = olefile.OleFileIO(filename)
    dirs = f.listdir()

    # HWP 파일 검증
    if ["FileHeader"] not in dirs or \
            ["\x05HwpSummaryInformation"] not in dirs:
        raise Exception("Not Valid HWP.")

    # 문서 포맷 압축 여부 확인
    header = f.openstream("FileHeader")
    header_data = header.read()
    is_compressed = (header_data[36] & 1) == 1

    # Body Sections 불러오기
    nums = []
    for d in dirs:
        if d[0] == "BodyText":
            nums.append(int(d[1][len("Section"):]))
    sections = ["BodyText/Section" + str(x) for x in sorted(nums)]

    # 전체 text 추출
    text = ""
    for section in sections:
        bodytext = f.openstream(section)
        data = bodytext.read()
        if is_compressed:
            unpacked_data = zlib.decompress(data, -15)
        else:
            unpacked_data = data

        # 각 Section 내 text 추출
        section_text = ""
        i = 0
        size = len(unpacked_data)
        while i < size:
            header = struct.unpack_from("<I", unpacked_data, i)[0]
            rec_type = header & 0x3ff
            rec_len = (header >> 20) & 0xfff

            if rec_type in [67]:
                rec_data = unpacked_data[i + 4:i + 4 + rec_len]
                section_text += rec_data.decode('utf-16')
                section_text += "\n"

            i += 4 + rec_len

        text += section_text
        text += "\n"

    return text

text = get_hwp_text('./file.hwp')
print(text)

인용한 코드이므로 출처를 남겨둡니다.

 

[Python] 각종 문서에서 텍스트 추출하기

이번 포스팅에서는 Python을 사용해 문서 파일을 파싱하여 텍스트를 추출하는 방법에 대해 알아보자. 문서...

blog.naver.com

이상한 찌꺼기 코드

이 코드를 사용하면 한글파일 전체 텍스트를 긁어올 수 있으나 위와같이 한자와 이상한 텍스트 찌꺼기가 끼여 있습니다. 출처에서도 해당 부분을 제거하지 못했는데요. 저도 여러가지 시도해 봤지만 아직 완전히 제거하지 못했습니다. 특히 저 네모에 사선이 있는 것은 텍스트가 특정되지 않아서 strip()으로도 제거가 안되네요. 깔끔하게 정리하는 방법을 찾으면 추가로 올리겠습니다.

 

   

본 코드에 제가 필요한 부분이지만 미흡한 부분도 있습니다. 표 안에 자료를 순서대로 잘 불러오긴 하는데 표 안에 공백이 있을 경우 별다른 표시 없이 다음 텍스트가 바로 붙어 버리네요. 손을좀 봐야할 거 같습니다.

반응형

댓글