[PYTHON] PDF 파일에서 텍스트를 추출하는 방법은 무엇입니까?
PYTHONPDF 파일에서 텍스트를 추출하는 방법은 무엇입니까?
파이썬을 사용하여이 PDF 파일에 포함 된 텍스트를 추출하려고합니다.
나는 PyPDF2 모듈을 사용하고 있으며 다음과 같은 스크립트를 가지고있다 :
import PyPDF2
pdf_file = open('sample.pdf')
read_pdf = PyPDF2.PdfFileReader(pdf_file)
number_of_pages = read_pdf.getNumPages()
page = read_pdf.getPage(0)
page_content = page.extractText()
print page_content
코드를 실행하면 PDF 문서에 포함 된 내용과 다른 다음 출력이 표시됩니다.
!"#$%#$%&%$&'()*%+,-%./01'*23%4
5'%1$#26%3/%7/))/8%&)/26%8#3"%3"*%313/9#&)
%
PDF 문서에있는대로 텍스트를 추출하려면 어떻게해야합니까?
해결법
-
==============================
1.textract를 사용하십시오.
textract를 사용하십시오.
그것은 PDF를 포함하여 많은 종류의 파일을 지원합니다
import textract text = textract.process("path/to/file.extension")
-
==============================
2.이 코드를보십시오 :
이 코드를보십시오 :
import PyPDF2 pdf_file = open('sample.pdf', 'rb') read_pdf = PyPDF2.PdfFileReader(pdf_file) number_of_pages = read_pdf.getNumPages() page = read_pdf.getPage(0) page_content = page.extractText() print page_content.encode('utf-8')
출력은 다음과 같습니다.
!"#$%#$%&%$&'()*%+,-%./01'*23%4 5'%1$#26%3/%7/))/8%&)/26%8#3"%3"*%313/9#&) %
동일한 코드를 사용하여 201308FCR.pdf에서 pdf를 읽으십시오. 출력은 정상입니다.
그 문서는 이유를 설명합니다 :
def extractText(self): """ Locate all text drawing commands, in the order they are provided in the content stream, and extract the text. This works well for some PDF files, but poorly for others, depending on the generator used. This will be refined in the future. Do not rely on the order of text coming out of this function, as it will change if this function is made more sophisticated. :return: a unicode string object. """
-
==============================
3.파이썬 3.x와 윈도우에 사용할 간단한 솔루션을 찾고있었습니다. textract에서 지원하지 않는 것 같습니다. 불행한 일이지만, Windows / Python 3 Checkout에 대한 간단한 솔루션을 찾으려면 tika 패키지를 사용하십시오.
파이썬 3.x와 윈도우에 사용할 간단한 솔루션을 찾고있었습니다. textract에서 지원하지 않는 것 같습니다. 불행한 일이지만, Windows / Python 3 Checkout에 대한 간단한 솔루션을 찾으려면 tika 패키지를 사용하십시오.
from tika import parser raw = parser.from_file('sample.pdf') print(raw['content'])
-
==============================
4.textpar (너무 많은 의존성이있는 것 같음)와 pypdf2 (테스트 한 pdfs에서 텍스트를 추출 할 수 없음) 및 tika (너무 느림)를 시도한 후에 xpdf에서 pdftotext를 사용하여 종료했습니다 (이미 다른 답변에서 제안 된대로) 방금 파이썬에서 바이너리를 직접 호출했습니다 (pdftotext에 경로를 적용해야 할 수도 있음).
textpar (너무 많은 의존성이있는 것 같음)와 pypdf2 (테스트 한 pdfs에서 텍스트를 추출 할 수 없음) 및 tika (너무 느림)를 시도한 후에 xpdf에서 pdftotext를 사용하여 종료했습니다 (이미 다른 답변에서 제안 된대로) 방금 파이썬에서 바이너리를 직접 호출했습니다 (pdftotext에 경로를 적용해야 할 수도 있음).
import os, subprocess SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) args = ["/usr/local/bin/pdftotext", '-enc', 'UTF-8', "{}/my-pdf.pdf".format(SCRIPT_DIR), '-'] res = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output = res.stdout.decode('utf-8')
pdftotext는 기본적으로 동일하지만 pdftotext는 / usr / local / bin에있는 반면 AWS 람다에서는 이것을 사용하고 현재 디렉토리에서 사용하려고합니다.
Btw : 람다에서 이것을 사용하려면 바이너리와 의존성을 libstdc ++에 넣어 라. 람다 함수에 넣어야한다. 필자는 개인적으로 xpdf를 컴파일해야했습니다. 이것에 대한 지시가이 대답을 날려 버릴 것이므로 나는 그들을 내 개인 블로그에 올려 놓았다.
-
==============================
5.pyPDF2가 텍스트 추출과 관련하여 여전히 여러 가지 문제가있는 것처럼 보이는 대신 xPDF 및 파생 툴을 사용하여 텍스트를 추출하는 것이 좋습니다.
pyPDF2가 텍스트 추출과 관련하여 여전히 여러 가지 문제가있는 것처럼 보이는 대신 xPDF 및 파생 툴을 사용하여 텍스트를 추출하는 것이 좋습니다.
긴 대답은 PDF 내에서 텍스트가 인코딩되는 방식이 다양하고 PDF 문자열 자체를 해독해야하는 경우 CMAP로 매핑해야 할 수 있다는 점입니다. 그런 다음 단어와 문자 사이의 거리를 분석해야 할 수도 있습니다.
PDF가 손상된 경우 (즉, 올바른 텍스트를 표시하지만 가비지를 복사 할 때) 실제로 텍스트를 추출해야하는 경우 PDF를 ImageMagik을 사용하여 이미지로 변환 한 다음 Tesseract를 사용하여 이미지에서 텍스트를 가져 오는 것이 좋습니다 OCR 사용.
-
==============================
6.아래의 코드는 Python 3의 질문에 대한 해결책입니다. 코드를 실행하기 전에, 여러분의 환경에 PyPDF2 라이브러리를 설치했는지 확인하십시오. 설치되어 있지 않은 경우 명령 프롬프트를 열고 다음 명령을 실행하십시오.
아래의 코드는 Python 3의 질문에 대한 해결책입니다. 코드를 실행하기 전에, 여러분의 환경에 PyPDF2 라이브러리를 설치했는지 확인하십시오. 설치되어 있지 않은 경우 명령 프롬프트를 열고 다음 명령을 실행하십시오.
pip3 install PyPDF2
솔루션 코드 :
import PyPDF2 pdfFileObject = open('sample.pdf', 'rb') pdfReader = PyPDF2.PdfFileReader(pdfFileObject) count = pdfReader.numPages for i in range(count): page = pdfReader.getPage(i) print(page.extractText())
-
==============================
7.PDFtoText를 사용할 수 있습니다. https://github.com/jalan/pdftotext
PDFtoText를 사용할 수 있습니다. https://github.com/jalan/pdftotext
PDF로 텍스트를 텍스트 형식으로 들여 쓰기 할 수 있습니다. 테이블이 있으면 중요하지 않습니다.
-
==============================
8.다중 페이지 pdf는 아래 코드를 사용하여 개별 페이지 번호를 인수로 제공하는 대신 단일 스트레치로 텍스트로 추출 할 수 있습니다
다중 페이지 pdf는 아래 코드를 사용하여 개별 페이지 번호를 인수로 제공하는 대신 단일 스트레치로 텍스트로 추출 할 수 있습니다
import PyPDF2 import collections pdf_file = open('samples.pdf', 'rb') read_pdf = PyPDF2.PdfFileReader(pdf_file) number_of_pages = read_pdf.getNumPages() c = collections.Counter(range(number_of_pages)) for i in c: page = read_pdf.getPage(i) page_content = page.extractText() print page_content.encode('utf-8')
-
==============================
9.이 작업을 수행하는 코드를 추가하고 있습니다. 그것은 나를 위해 잘 작동합니다 :
이 작업을 수행하는 코드를 추가하고 있습니다. 그것은 나를 위해 잘 작동합니다 :
# This works in python 3 # required python packages # tabula-py==1.0.0 # PyPDF2==1.26.0 # Pillow==4.0.0 # pdfminer.six==20170720 import os import shutil import warnings from io import StringIO import requests import tabula from PIL import Image from PyPDF2 import PdfFileWriter, PdfFileReader from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.pdfpage import PDFPage warnings.filterwarnings("ignore") def download_file(url): local_filename = url.split('/')[-1] local_filename = local_filename.replace("%20", "_") r = requests.get(url, stream=True) print(r) with open(local_filename, 'wb') as f: shutil.copyfileobj(r.raw, f) return local_filename class PDFExtractor(): def __init__(self, url): self.url = url # Downloading File in local def break_pdf(self, filename, start_page=-1, end_page=-1): pdf_reader = PdfFileReader(open(filename, "rb")) # Reading each pdf one by one total_pages = pdf_reader.numPages if start_page == -1: start_page = 0 elif start_page < 1 or start_page > total_pages: return "Start Page Selection Is Wrong" else: start_page = start_page - 1 if end_page == -1: end_page = total_pages elif end_page < 1 or end_page > total_pages - 1: return "End Page Selection Is Wrong" else: end_page = end_page for i in range(start_page, end_page): output = PdfFileWriter() output.addPage(pdf_reader.getPage(i)) with open(str(i + 1) + "_" + filename, "wb") as outputStream: output.write(outputStream) def extract_text_algo_1(self, file): pdf_reader = PdfFileReader(open(file, 'rb')) # creating a page object pageObj = pdf_reader.getPage(0) # extracting extract_text from page text = pageObj.extractText() text = text.replace("\n", "").replace("\t", "") return text def extract_text_algo_2(self, file): pdfResourceManager = PDFResourceManager() retstr = StringIO() la_params = LAParams() device = TextConverter(pdfResourceManager, retstr, codec='utf-8', laparams=la_params) fp = open(file, 'rb') interpreter = PDFPageInterpreter(pdfResourceManager, device) password = "" max_pages = 0 caching = True page_num = set() for page in PDFPage.get_pages(fp, page_num, maxpages=max_pages, password=password, caching=caching, check_extractable=True): interpreter.process_page(page) text = retstr.getvalue() text = text.replace("\t", "").replace("\n", "") fp.close() device.close() retstr.close() return text def extract_text(self, file): text1 = self.extract_text_algo_1(file) text2 = self.extract_text_algo_2(file) if len(text2) > len(str(text1)): return text2 else: return text1 def extarct_table(self, file): # Read pdf into DataFrame try: df = tabula.read_pdf(file, output_format="csv") except: print("Error Reading Table") return print("\nPrinting Table Content: \n", df) print("\nDone Printing Table Content\n") def tiff_header_for_CCITT(self, width, height, img_size, CCITT_group=4): tiff_header_struct = '<' + '2s' + 'h' + 'l' + 'h' + 'hhll' * 8 + 'h' return struct.pack(tiff_header_struct, b'II', # Byte order indication: Little indian 42, # Version number (always 42) 8, # Offset to first IFD 8, # Number of tags in IFD 256, 4, 1, width, # ImageWidth, LONG, 1, width 257, 4, 1, height, # ImageLength, LONG, 1, lenght 258, 3, 1, 1, # BitsPerSample, SHORT, 1, 1 259, 3, 1, CCITT_group, # Compression, SHORT, 1, 4 = CCITT Group 4 fax encoding 262, 3, 1, 0, # Threshholding, SHORT, 1, 0 = WhiteIsZero 273, 4, 1, struct.calcsize(tiff_header_struct), # StripOffsets, LONG, 1, len of header 278, 4, 1, height, # RowsPerStrip, LONG, 1, lenght 279, 4, 1, img_size, # StripByteCounts, LONG, 1, size of extract_image 0 # last IFD ) def extract_image(self, filename): number = 1 pdf_reader = PdfFileReader(open(filename, 'rb')) for i in range(0, pdf_reader.numPages): page = pdf_reader.getPage(i) try: xObject = page['/Resources']['/XObject'].getObject() except: print("No XObject Found") return for obj in xObject: try: if xObject[obj]['/Subtype'] == '/Image': size = (xObject[obj]['/Width'], xObject[obj]['/Height']) data = xObject[obj]._data if xObject[obj]['/ColorSpace'] == '/DeviceRGB': mode = "RGB" else: mode = "P" image_name = filename.split(".")[0] + str(number) print(xObject[obj]['/Filter']) if xObject[obj]['/Filter'] == '/FlateDecode': data = xObject[obj].getData() img = Image.frombytes(mode, size, data) img.save(image_name + "_Flate.png") # save_to_s3(imagename + "_Flate.png") print("Image_Saved") number += 1 elif xObject[obj]['/Filter'] == '/DCTDecode': img = open(image_name + "_DCT.jpg", "wb") img.write(data) # save_to_s3(imagename + "_DCT.jpg") img.close() number += 1 elif xObject[obj]['/Filter'] == '/JPXDecode': img = open(image_name + "_JPX.jp2", "wb") img.write(data) # save_to_s3(imagename + "_JPX.jp2") img.close() number += 1 elif xObject[obj]['/Filter'] == '/CCITTFaxDecode': if xObject[obj]['/DecodeParms']['/K'] == -1: CCITT_group = 4 else: CCITT_group = 3 width = xObject[obj]['/Width'] height = xObject[obj]['/Height'] data = xObject[obj]._data # sorry, getData() does not work for CCITTFaxDecode img_size = len(data) tiff_header = self.tiff_header_for_CCITT(width, height, img_size, CCITT_group) img_name = image_name + '_CCITT.tiff' with open(img_name, 'wb') as img_file: img_file.write(tiff_header + data) # save_to_s3(img_name) number += 1 except: continue return number def read_pages(self, start_page=-1, end_page=-1): # Downloading file locally downloaded_file = download_file(self.url) print(downloaded_file) # breaking PDF into number of pages in diff pdf files self.break_pdf(downloaded_file, start_page, end_page) # creating a pdf reader object pdf_reader = PdfFileReader(open(downloaded_file, 'rb')) # Reading each pdf one by one total_pages = pdf_reader.numPages if start_page == -1: start_page = 0 elif start_page < 1 or start_page > total_pages: return "Start Page Selection Is Wrong" else: start_page = start_page - 1 if end_page == -1: end_page = total_pages elif end_page < 1 or end_page > total_pages - 1: return "End Page Selection Is Wrong" else: end_page = end_page for i in range(start_page, end_page): # creating a page based filename file = str(i + 1) + "_" + downloaded_file print("\nStarting to Read Page: ", i + 1, "\n -----------===-------------") file_text = self.extract_text(file) print(file_text) self.extract_image(file) self.extarct_table(file) os.remove(file) print("Stopped Reading Page: ", i + 1, "\n -----------===-------------") os.remove(downloaded_file) # I have tested on these 3 pdf files # url = "http://s3.amazonaws.com/NLP_Project/Original_Documents/Healthcare-January-2017.pdf" url = "http://s3.amazonaws.com/NLP_Project/Original_Documents/Sample_Test.pdf" # url = "http://s3.amazonaws.com/NLP_Project/Original_Documents/Sazerac_FS_2017_06_30%20Annual.pdf" # creating the instance of class pdf_extractor = PDFExtractor(url) # Getting desired data out pdf_extractor.read_pages(15, 23)
-
==============================
10.다음은 텍스트 추출을위한 가장 간단한 코드입니다
다음은 텍스트 추출을위한 가장 간단한 코드입니다
암호:
# importing required modules import PyPDF2 # creating a pdf file object pdfFileObj = open('filename.pdf', 'rb') # creating a pdf reader object pdfReader = PyPDF2.PdfFileReader(pdfFileObj) # printing number of pages in pdf file print(pdfReader.numPages) # creating a page object pageObj = pdfReader.getPage(5) # extracting text from page print(pageObj.extractText()) # closing the pdf file object pdfFileObj.close()
-
==============================
11.어떤 경우에는 PyPDF2가 공백을 무시하고 결과 텍스트를 엉망으로 만들지 만 PyMuPDF를 사용하면 정말 만족 스럽습니다. 이 링크를 사용하여 자세한 정보를 얻을 수 있습니다.
어떤 경우에는 PyPDF2가 공백을 무시하고 결과 텍스트를 엉망으로 만들지 만 PyMuPDF를 사용하면 정말 만족 스럽습니다. 이 링크를 사용하여 자세한 정보를 얻을 수 있습니다.
-
==============================
12.여기에서 tika-app-xxx.jar (latest)를 다운로드 할 수 있습니다.
여기에서 tika-app-xxx.jar (latest)를 다운로드 할 수 있습니다.
그런 다음이 .jar 파일을 파이썬 스크립트 파일의 같은 폴더에 넣으십시오.
그런 다음 스크립트에 다음 코드를 삽입하십시오.
import os import os.path tika_dir=os.path.join(os.path.dirname(__file__),'<tika-app-xxx>.jar') def extract_pdf(source_pdf:str,target_txt:str): os.system('java -jar '+tika_dir+' -t {} > {}'.format(source_pdf,target_txt))
의존성 감소. 단일 .jar 파일은 파이썬 패키지보다 관리하기 쉽습니다.
멀티 포맷 지원. source_pdf 위치는 모든 종류의 문서 디렉토리 일 수 있습니다. (.doc, .html, .odt 등)
최신 정보. tika-app.jar는 항상 tika python 패키지의 관련 버전보다 먼저 릴리스됩니다.
안정된. PyPDF보다 훨씬 안정적이고 유지 보수가 잘됩니다.
jre-headless가 필요합니다.
from https://stackoverflow.com/questions/34837707/how-to-extract-text-from-a-pdf-file by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] if 문에서 초기화 된 변수의 범위는 무엇입니까? (0) | 2018.10.06 |
---|---|
[PYTHON] 어떻게하면 Python 프로그램을 실행할 수 있습니까? (0) | 2018.10.06 |
[PYTHON] 파이썬에서 굵은 텍스트를 어떻게 인쇄합니까? (0) | 2018.10.06 |
[PYTHON] Python / Django를 사용하여 HTML 디코딩 / 인코딩을 수행하려면 어떻게해야합니까? (0) | 2018.10.06 |
[PYTHON] POST 요청을 보내는 방법? (0) | 2018.10.06 |