파이썬에서 PDF를 조작할 때 비교적 사용하기 쉬운 라이브러리 PDFMiner3K가 있습니다. 매우 유연하여 명령줄에서도 사용할 수 있고, 기존 코드에 통합할 수도 있습니다.
다음은 임의의 PDF를 로컬 파일 객체로 바꿔서 문자열로 읽는 기본적인 프로그램입니다.
from urllib.request import urlopen
from pdfminer.pdfinterp import PDFResourceManager, process_pdf
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from io import StringIO
from io import open
def readPDF(pdfFile):
rsrcmgr = PDFResourceManager()
retstr = String()
laprams = LAParam()
device = TextConverter(rsrcmgr, retstr, laparams=laparms)
process_pdf(rsrcmgr, device, pdfFile)
device.close()
content = retstr.getvalue()
retstr.close()
return content
pdfFile = urlopen('http://pythonscraping.com/pages/warandpeace/chapter1.pdf')
outputString = readPDF(pdfFIle)
print(outputString)
pdfFile.close()
마이크로소프트 워드와 .docx
마이크로소프트는 여러 표준을 받아들여 오픈 오피스 XML 기반 표준을 사용하기로 결정했습니다. 파이썬은 구글 독스와 오픈 오피스, 마이크로소프트 오피스에서 사용하는 파일 형식을 아직 잘 지원하지 못하고 있습니다.(21.06)
python-docx 라이브러리는 문서를 만들거나 파일 크기와 타이틀 같은 기본적인 파일 데이터를 읽을 뿐, 실제 콘텐츠를 읽지는 못합니다. 마이크로소프트 파일을 읽으려면 직접 해결책을 만들어야 합니다.
파일에서 XML을 읽는 첫 번째 단계는 다음과 같습니다.
from zipfile import ZipFile
from urllib.request import urlopen
from io import BytesIO
wordFile = urlopen('http://pythonscraping.com/pages/AWordDocument.docs').read()
wordFile = ByteIO(wordFile)
document = ZipFile(wordFile)
xml_content = document.read('word/document.xml')
print(xml_content.decode('utf-8')
위와 같은 코드가 결과를 출력하면, 메타데이터는 많이있지만, 정작 필요한 텍스트 콘텐츠는 파묻혀있을 겁니다. 다행히 상단의 타이틀을 포함해 문서의 텍스트는 모드 <w:t> 태그 안에 들어 있으므로 추출하기 쉽습니다.
from zipfile import ZipFile
from urllib.request import urlopen
from io import BytesIO
wordFile = urlopen('http://pythonscraping.com/pages/AWordDocument.docs').read()
wordFile = ByteIO(wordFile)
document = ZipFile(wordFile)
xml_content = document.read('word/document.xml')
print(xml_content.decode('utf-8')
wordObj = BeautifulSoup(xml_content.decode('utf-8')
textStrings = wordObj.findAll("w:t")
for textElem in textStrings:
print(textElem.text)
위와 같이 작성하여도, 아직 문제가 있을 겁니다. 다양한 경우가 있겠지만, 다른 태그에 둘러쌓여 있는경우 BeautifulSoup의 내비게이션 기능을 유용하게 쓸 수 있습니다.
textStrings = wordObj.findAl("w:t")
for textElem in textStrings:
closeTag = ""
try:
style = textElem.parent.previousSibling.find("w:pstyle")
if style is not None and style["w:val"] == "Title":
print("<h1>")
closeTag = "</h1>"
except AttributeArror:
# 출력할 태그가 없습니다.
pass
print(textElem.text)
print(coseTag)
'IT > Scraping' 카테고리의 다른 글
지저분한 데이터 정리하기: 사후 정리(오픈리파인, OpenRefine) (0) | 2025.02.20 |
---|---|
지저분한 데이터 정리하기: 코드에서 정리 (0) | 2025.02.20 |
문서 읽기: 텍스트, CSV (0) | 2025.02.18 |
웹 크롤러 모델: 여러 페이지 유형 크롤러 그리고 좋은 웹크로러 (0) | 2025.02.16 |
웹 크롤링 모델: 링크를 통한 사이트 크롤링 (0) | 2025.02.16 |