# LangChain 모듈 사용하는 방법
langchain에서 제공하는 document_loaders 를 이용하면 파일의 내용들을 손쉽게 파싱할 수 있다.
- PDF: PyPDFLoader
- eml: UnstructuredEmailLoader
- xlsx: UnstructuredExcelLoader
- docx: Docx2txtLoader
- pptx: UnstructuredPowerPointLoader
from langchain_community.document_loaders import (
PyPDFLoader, # .pdf
UnstructuredEmailLoader, # .eml
UnstructuredExcelLoader, # .xlsx, .xls
Docx2txtLoader, # .docx
UnstructuredPowerPointLoader, # .pptx
)
import htmltabletomd
def read_pdf(file_path:str)->str:
'''
Function which parses .pdf
params:
- file_path(str)
returns:
- (str)
'''
loader = PyPDFLoader(file_path)
docs = loader.load()
doc_content = ""
for doc in docs:
doc_content+= doc.page_content+"\n"
return doc_content
def read_eml(file_path:str)->str:
'''
Function which parses .eml. This includes message only.
params:
- file_path(str)
returns:
- (str)
'''
loader = UnstructuredEmailLoader(file_path, mode="elements")
docs = loader.load()
doc_content = ''
for doc in docs:
if "message" in doc.metadata["filetype"]:
doc_content+=doc.page_content+"\n"
# doc = Document(page_content=doc_content, metadata=docs[0].metadata)
return doc_content
def read_excel(file_path:str)->str:
'''
Function which parses .xlsx. This attaches sheet name as a header.
params:
- file_path(str)
returns:
- (str)
'''
loader = UnstructuredExcelLoader(file_path, mode="elements")
docs = loader.load()
doc_content=""
for doc in docs:
doc_content="# 시트명: {}\n".format(doc.metadata["page_name"])
if "text_as_html" in doc.metadata:
doc_content += htmltabletomd.convert_table(doc.metadata["text_as_html"])
else:
doc_content += doc.page_content.strip()
return doc_content
def read_docx(file_path:str)->str:
'''
Function which parses .docx
params:
- file_path(str)
returns:
- (str)
'''
loader = Docx2txtLoader(file_path)
docs = loader.load()
doc_content = ""
for doc in docs:
doc_content+= doc.page_content+"\n"
return doc_content
def read_pptx(file_path:str)->str:
'''
Function which parses .pptx
params:
- file_path(str)
returns:
- (str)
'''
loader = UnstructuredPowerPointLoader(file_path)
docs = loader.load()
doc_content = ""
for doc in docs:
doc_content+= doc.page_content+"\n"
return doc_content
`htmltabletomd` 모듈은 이름 그대로 html의 표를 마크다운 표 형식으로 바꿔주는 모듈임
엑셀에서 텍스트만 파싱하면 탭과 줄바꿈으로만 파싱되어서 셀이 잘 구분이 안되길래 `mode="elements"` 옵션을 사용해서 html 형식으로 엑셀을 파싱한 후, 마크다운 형식으로 변환해줬다.
# MS Office 파일(.docx, .pptx, .xlsx) 불러오기
아래의 방법들은 Langchain 모듈 없이 다른 라이브러리로 읽는 방법이다.
- python-docx: .docx 파일을 다룰 때 사용
- openpyxl: .xlsx 파일을 다룰 때 사용
- python-pptx: .pptx 파일을 다룰 때 사용
pip install python-docx openpyxl python-pptx
1) 워드 파일 읽기 (.docx)
# docx 파일 읽기
from docx import Document
def read_docx(file_path):
doc = Document(file_path)
full_text = []
for para in doc.paragraphs:
full_text.append(para.text)
return '\n'.join(full_text)
# 사용 예시
file_path = 'your_doc_file.docx'
text = read_docx(file_path)
print(text)
2) ppt 파일 읽기 (.pptx)
from pptx import Presentation
def read_pptx(file_path:str)->str:
loader = Presentation(file_path)
doc_content = ""
for slide in loader.slides:
for shape in slide.shapes:
if not shape.has_text_frame:
continue
for paragraph in shape.text_frame.paragraphs:
for run in paragraph.runs:
doc_content+= run.text+"\n"
doc_content+="\n"
return doc_content
# 사용 예시
file_path = 'your_file.pptx'
text = read_pptx(file_path)
print(text)
3) 엑셀 파일 읽기 (.xlsx)
from openpyxl import load_workbook
def read_xlsx(file_path):
workbook = load_workbook(filename=file_path)
sheet = workbook.active
data = []
for row in sheet.iter_rows(values_only=True):
data.append(list(row))
return data
# Example usage
xlsx_data = read_xlsx('sample.xlsx')
print(xlsx_data)
정형 데이터라 그런가 엑셀 읽는 라이브러리가 몇개 더 있는데 비교글을 보고 더 적합한 라이브러리를 고르면 될 듯
# pdf 파일 불러오기
잘 정리된 블로그를 발견했다.
이것저것 비교해보고 싶었는데 결국 가장 많이 쓰이는 것으로 보이는 (구글 검색 기준) PyPDF2 를 사용하기로...
# eml 파일 불러오기
eml 파일은 메일에 대한 정보가 헤더로 들어있다. 헤더는 바이트로 디코딩을 해줘야함
기본 내장 라이브러리인 `email` 을 사용했다. 이 라이브러리는 `python>=3.5` 에서 부터 적용이 되는 듯...
import email
from email.header import decode_header
from bs4 import BeautifulSoup
def read_eml(file_path:str)->str:
with open(file_path, "rb") as loader:
docs = loader.read()
docs = email.message_from_bytes(docs)
decoded_bytes, charset = decode_header(docs.get('From'))[0]
sender = decoded_bytes.decode(charset)
decoded_bytes, charset = decode_header(docs.get('To'))[0]
recipient = decoded_bytes.decode(charset)
decoded_bytes, charset = decode_header(docs.get('Subject'))[0]
subject = decoded_bytes.decode(charset)
body = ""
attachments = []
for part in docs.walk():
content_type = part.get_content_type()
if content_type=='text/plain':
body += part.get_payload(decode=True).decode('utf-8', 'ignore')
elif content_type=='text/html':
html_body = part.get_payload(decode=True).decode('utf-8', 'ignore')
soup = BeautifulSoup(html_body, 'html.parser')
body += soup.get_text(strip=True,separator="\n")
elif content_type.startswith('application'):
decoded_bytes, charset = decode_header(part.get_filename())[0]
attachments.append(decoded_bytes.decode(charset))
doc_content = "발신자:{}\t 수신자:{}\n제목: {}\n본문: {}\n첨부파일:{}".format(sender, recipient, subject, body, ', '.join(attachments))
return doc_content
# 사용 예시
file_path = 'your_file.eml'
text = read_eml(file_path)
print(text)
Reference
[1] Python으로 PDF에서 텍스트 추출하기(pdf to text)
728x90