Làm cách nào để trích xuất văn bản từ tệp PDF?


190

Tôi đang cố gắng trích xuất văn bản có trong tệp PDF này bằng cách sử dụng Python.

Tôi đang sử dụng mô-đun PyPDF2 và có đoạn mã sau:

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

Khi tôi chạy mã, tôi nhận được đầu ra sau khác với đầu ra có trong tài liệu PDF:

!"#$%#$%&%$&'()*%+,-%./01'*23%4
5'%1$#26%3/%7/))/8%&)/26%8#3"%3"*%313/9#&)
%

Làm cách nào tôi có thể trích xuất văn bản như trong tài liệu PDF?


9
Tôi chưa bao giờ sử dụng mô-đun đó, nhưng nó có tạo ra sự khác biệt nếu bạn mở tệp ở chế độ nhị phân : pdf_file = open('sample.pdf', 'rb')?
PM 2Ring

2
Cảm ơn vì đã trả lời. Tôi đã thử điều đó với chế độ nhị phân, nhưng không có gì thay đổi
Đơn giản

3
Sao chép văn bản bằng trình xem PDF tốt - Acrobat Reader chuẩn của Adobe, nếu có thể. Bạn có nhận được kết quả tương tự? Sự khác biệt không phải là văn bản khác nhau, mà là phông chữ - mã ký tự ánh xạ tới các giá trị khác. Không phải tất cả các tệp PDF đều chứa dữ liệu chính xác để khôi phục điều này.
usr2564301

2
Bản PDF đó chứa bảng CMap ký tự, do đó, các hạn chế và cách giải quyết được thảo luận trong chuỗi này là có liên quan - stackoverflow.com/questions/4203414/ .
thức

2
PDF thực sự chứa một CMAP chính xác, vì vậy việc chuyển đổi ánh xạ ký tự ad hoc thành văn bản thuần túy là chuyện nhỏ. Tuy nhiên, phải xử lý bổ sung để lấy đúng thứ tự văn bản. Trình kết xuất Quartz PDF của Mac OS X là một công việc khó chịu! Theo thứ tự kết xuất ban đầu, tôi nhận được "m T'h iuss iisn ga tosam fopllloew DalFo dnogc wumithe ntht eI guide" ... Chỉ sau khi sắp xếp theo tọa độ x tôi mới nhận được kết quả chính xác hơn nhiều: "Đây là tài liệu PDF mẫu. Tôi đang sử dụng để làm theo cùng với hướng dẫn ".
usr2564301

Câu trả lời:


199

Tôi đang tìm kiếm một giải pháp đơn giản để sử dụng cho python 3.x và windows. Dường như không có sự hỗ trợ từ textract , điều này thật đáng tiếc, nhưng nếu bạn đang tìm kiếm một giải pháp đơn giản cho windows / python 3, hãy kiểm tra gói tika , thực sự rất dễ dàng để đọc pdf.

Tika-Python là một ràng buộc Python với các dịch vụ Apache Tika ™ REST cho phép Tika được gọi là nguyên bản trong cộng đồng Python.

from tika import parser # pip install tika

raw = parser.from_file('sample.pdf')
print(raw['content'])

Lưu ý rằng Tika được viết bằng Java, do đó bạn sẽ cần cài đặt thời gian chạy Java


17
Tôi đã thử nghiệm pypdf2, tika và đã thử và thất bại trong việc cài đặt textract và pdftotext. Pypdf2 trả lại 99 từ trong khi tika trả lại tất cả 858 từ từ hóa đơn kiểm tra của tôi. Vì vậy, tôi đã kết thúc với tika.
Stian

8
Người đàn ông anh yêu em. Tôi không biết tại sao một câu trả lời hay như vậy lại bị ẩn trong StackOverflow. Mọi người cứ nhắc rằng chúng tôi cần sử dụng PyPDF2 hoặc pdfminer nhưng chúng bốc mùi. Bây giờ tôi đang yêu tika
jxpython

15
Tôi liên tục gặp lỗi "RuntimeError: Không thể khởi động máy chủ Tika".
Nav

3
Trả lời Tôi đã tìm kiếm cả đời, tại sao không ai khác giới thiệu Tika? Cảm ơn!
Jacob-Jan Mosselman

4
Nếu bạn cần chạy tệp này trên tất cả các tệp PDF trong một thư mục (đệ quy), hãy lấy tập lệnh này
Hy vọng

58

Sử dụng textract.

Nó hỗ trợ nhiều loại tệp bao gồm các tệp PDF

import textract
text = textract.process("path/to/file.extension")

24
Textwrap dường như là một trình bao bọc đẹp, nhưng phụ thuộc vào nhiều tiện ích không phải Python có thể không dễ dàng có sẵn trên một hệ thống nhất định.
David Brown

1
Hoạt động cho PDF, epub, v.v. - xử lý các tệp PDF mà ngay cả PDFMiner cũng không thành công.
Ulad Kasach

Làm thế nào để sử dụng nó trong aws lambda, tôi đã thử điều này nhưng, lỗi nhập xảy ra lỗi văn bản
Arun Kumar

5
textractlà một gói cho Poppler:pdftotext(trong số những người khác).
onewhaleid

1
@ArunKumar: Để sử dụng bất cứ thứ gì trong AWS Lambda không được tích hợp sẵn, bạn phải bao gồm nó và tất cả các phụ thuộc bổ sung, trong gói của bạn.
Jeff Learman

51

Nhìn vào mã này:

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

Đầu ra là:

!"#$%#$%&%$&'()*%+,-%./01'*23%4
5'%1$#26%3/%7/))/8%&)/26%8#3"%3"*%313/9#&)
%

Sử dụng cùng một mã để đọc pdf từ 201308FCR.pdf . Đầu ra là bình thường.

Tài liệu của nó giải thích tại sao:

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

@VineeshTP: Bạn có nhận được gì cho page_content không? Nếu có, hãy xem nếu nó giúp bằng cách sử dụng một mã hóa khác ngoài (utf-8)
Quinn

Thư viện tốt nhất tôi tìm thấy để đọc pdf bằng python là 'tika'
Vineesh TP 15/07/19

201308FCR.pdf không tìm thấy.
Chaitanya Bapat

30

Sau khi thử textract (dường như có quá nhiều phụ thuộc) và pypdf2 (không thể trích xuất văn bản từ pdf mà tôi đã thử) và tika (quá chậm) tôi đã kết thúc bằng pdftotextxpdf (như đã đề xuất trong câu trả lời khác) và chỉ được gọi trực tiếp là nhị phân từ python (bạn có thể cần điều chỉnh đường dẫn đến 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 về cơ bản là giống nhau nhưng điều này giả sử pdftotext trong / usr / local / bin trong khi tôi đang sử dụng nó trong AWS lambda và muốn sử dụng nó từ thư mục hiện tại.

Btw: Để sử dụng điều này trên lambda, bạn cần đặt nhị phân và sự phụ thuộc libstdc++.sovào chức năng lambda của bạn. Cá nhân tôi cần phải biên dịch xpdf. Theo hướng dẫn cho điều này sẽ làm nổ tung câu trả lời này, tôi đưa chúng lên blog cá nhân của mình .


4
Trời ơi, nó hoạt động !! Cuối cùng, một giải pháp trích xuất văn bản theo đúng thứ tự! Tôi muốn ôm bạn vì câu trả lời này! (Hoặc nếu bạn không thích những cái ôm, đây là cà phê / bia ​​ảo / ...)
DonQuiKong 27/11/18

4
rất vui vì nó đã giúp Upvote mang lại cảm giác giống như ôm, vì vậy tôi ổn!
hansaplast

đơn giản ... gr8 ra khỏi suy nghĩ!
shantanu pathak

10

Bạn có thể muốn sử dụng xPDF đã được chứng minh bằng thời gian và các công cụ dẫn xuất để trích xuất văn bản thay vì pyPDF2 dường như vẫn còn nhiều vấn đề khác với việc trích xuất văn bản.

Câu trả lời dài là có rất nhiều biến thể về cách một văn bản được mã hóa bên trong PDF và nó có thể yêu cầu tự giải mã chuỗi PDF, sau đó có thể cần ánh xạ với CMAP, sau đó có thể cần phân tích khoảng cách giữa các từ và chữ cái, v.v.

Trong trường hợp PDF bị hỏng (tức là hiển thị văn bản chính xác nhưng khi sao chép nó sẽ tạo ra rác) và bạn thực sự cần trích xuất văn bản, thì bạn có thể muốn xem xét chuyển đổi PDF thành hình ảnh (sử dụng ImageMagik ) và sau đó sử dụng Tesseract để lấy văn bản từ hình ảnh sử dụng OCR.


-1 vì OP đang yêu cầu đọc pdf bằng Python và mặc dù có trình bao bọc xpdf cho python nhưng nó vẫn được duy trì kém.
cduguet

9

Tôi đã thử nhiều trình chuyển đổi Python PDF và tôi muốn cập nhật đánh giá này. Tika là một trong những tốt nhất. Nhưng PyMuPDF là một tin tốt từ người dùng @ehsaneha.

Tôi đã làm một mã để so sánh chúng trong: https://github.com/erfelipe/PDFtextExtraction Tôi hy vọng sẽ giúp bạn.

Tika-Python là một ràng buộc Python với các dịch vụ Apache Tika ™ REST cho phép Tika được gọi là nguyên bản trong cộng đồng Python.

from tika import parser

raw = parser.from_file("///Users/Documents/Textos/Texto1.pdf")
raw = str(raw)

safe_text = raw.encode('utf-8', errors='ignore')

safe_text = str(safe_text).replace("\n", "").replace("\\", "")
print('--- safe text ---' )
print( safe_text )

3
cảm ơn đặc biệt cho.encode('utf-8', errors='ignore')
Evgeny

AttributionError: mô-đun 'os' không có thuộc tính 'setsid'
keramat

7

Đoạn mã dưới đây là một giải pháp cho câu hỏi trong Python 3 . Trước khi chạy mã, đảm bảo bạn đã cài đặt PyPDF2thư viện trong môi trường của mình. Nếu không được cài đặt, hãy mở dấu nhắc lệnh và chạy lệnh sau:

pip3 install PyPDF2

Mã giải pháp:

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

2
Làm thế nào bạn có thể lưu tất cả nội dung trong một tệp văn bản và sử dụng nó để phân tích thêm
Rahul Agarwal

7
Điều này không giải quyết vấn đề được đề cập trong câu hỏi thực tế.
Soumik Rakshit

7

PyPDF2 trong một số trường hợp bỏ qua khoảng trắng và làm cho văn bản kết quả trở nên lộn xộn, nhưng tôi sử dụng PyMuPDF và tôi thực sự hài lòng, bạn có thể sử dụng liên kết này để biết thêm


pymupdf là giải pháp tốt nhất tôi quan sát được, không yêu cầu các thư viện C ++ bổ sung như pdftotext hoặc java như tika
Kay

pymypdf thực sự là giải pháp tốt nhất, không có máy chủ hoặc thư viện bổ sung và nó hoạt động với tệp trong đó PyPDF2 PypDF3 PyPDF4 lấy lại chuỗi văn bản trống. cảm ơn nhiều!
Andrea Bisello

để cài đặt pymupdf, chạy pip install pymupdf==1.16.16. Sử dụng phiên bản cụ thể này vì ngày nay phiên bản mới nhất (17) không hoạt động. Tôi đã chọn pymupdf vì nó trích xuất các trường gói văn bản trong dòng char mới \n. Vì vậy, tôi đang trích xuất văn bản từ pdf thành một chuỗi bằng pymupdf và sau đó tôi đang sử dụng my_extracted_text.splitlines()để đưa văn bản được chia thành các dòng, vào một danh sách.
erickfis

PyMuPDF thực sự đáng ngạc nhiên. Cảm ơn.
erfelipe

6

pdftotext là tốt nhất và đơn giản nhất! pdftotext cũng bảo lưu cấu trúc là tốt.

Tôi đã thử PyPDF2, PDFMiner và một vài người khác nhưng không ai trong số họ cho kết quả khả quan.


Thông báo như sau khi cài đặt pdf2text Collecting PDFMiner (from pdf2text), vì vậy tôi không hiểu câu trả lời này ngay bây giờ.
zhy

pdf2text và pdftotext là khác nhau. Bạn có thể sử dụng liên kết từ câu trả lời.
Dharam

ĐỒNG Ý. Đó là một chút khó hiểu.
vào


5

Pdf nhiều trang có thể được trích xuất dưới dạng văn bản ở một đoạn thay vì đưa ra số trang riêng lẻ làm đối số sử dụng mã bên dưới

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

Chỉ có vấn đề ở đây, nội dung của trang mới ghi đè lên trang cuối cùng
Rahul Agarwal

3

Đây là mã đơn giản nhất để trích xuất văn bản

mã:

# 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()

Giới thiệu 'tika'
Vineesh TP

2

Tôi tìm thấy một giải pháp ở đây PDFLayoutTextStripper

Điều đó tốt bởi vì nó có thể giữ bố cục của PDF gốc .

Nó được viết bằng Java nhưng tôi đã thêm một Gateway để hỗ trợ Python.

Mã mẫu:

from py4j.java_gateway import JavaGateway

gw = JavaGateway()
result = gw.entry_point.strip('samples/bus.pdf')

# result is a dict of {
#   'success': 'true' or 'false',
#   'payload': pdf file content if 'success' is 'true'
#   'error': error message if 'success' is 'false'
# }

print result['payload']

Đầu ra mẫu từ PDFLayoutTextStripper : nhập mô tả hình ảnh ở đây

Bạn có thể xem thêm chi tiết tại đây Vũ nữ thoát y với Python


2

Tôi đã có một công việc tốt hơn OCR và để duy trì căn chỉnh trang trong khi trích xuất văn bản từ PDF. Cần giúp đỡ:

from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from io import StringIO

def convert_pdf_to_txt(path):
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    fp = open(path, 'rb')
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    password = ""
    maxpages = 0
    caching = True
    pagenos=set()


    for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
        interpreter.process_page(page)


    text = retstr.getvalue()

    fp.close()
    device.close()
    retstr.close()
    return text

text= convert_pdf_to_txt('test.pdf')
print(text)

Nb. Phiên bản mới nhất không còn sử dụng codecarg . Tôi đã sửa lỗi này bằng cách loại bỏ nó tức làdevice = TextConverter(rsrcmgr, retstr, laparams=laparams)
Atomh33ls

1

Để trích xuất văn bản từ PDF, sử dụng mã bên dưới

import PyPDF2
pdfFileObj = open('mypdf.pdf', 'rb')

pdfReader = PyPDF2.PdfFileReader(pdfFileObj)

print(pdfReader.numPages)

pageObj = pdfReader.getPage(0)

a = pageObj.extractText()

print(a)

0

Tôi đang thêm mã để thực hiện điều này: Nó hoạt động tốt với tôi:

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

0

Bạn có thể tải xuống tika-app-xxx.jar (mới nhất) từ đây .

Sau đó đặt tệp .jar này vào cùng thư mục của tệp script python của bạn.

sau đó chèn đoạn mã sau vào tập lệnh:

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

Ưu điểm của phương pháp này:

phụ thuộc ít hơn. Tệp .jar đơn dễ quản lý gói python hơn.

hỗ trợ đa định dạng. Vị trí source_pdfcó thể là thư mục của bất kỳ loại tài liệu. (.doc, .html, .odt, v.v.)

cập nhật tika-app.jar luôn phát hành sớm hơn phiên bản có liên quan của gói tika python.

ổn định. Nó ổn định và được bảo trì tốt hơn (Powered by Apache) so với PyPDF.

bất lợi:

Một jre-headless là cần thiết.


hoàn toàn không phải là giải pháp pythonic. Nếu bạn đề xuất điều này, bạn nên xây dựng một gói python và có người nhập nó. Không khuyến nghị sử dụng thực thi dòng lệnh của mã java trong python.
Michael Tamvel

@MichaelTamvel, nếu viết một mã sắp được tải lên pypi, tôi thừa nhận rằng đó không phải là một ý tưởng tốt. Tuy nhiên, nếu nó chỉ là một kịch bản python với shebang để sử dụng tạm thời, nó không phải là xấu, phải không?
pah8J

Chà, câu hỏi không có tiêu đề với "python" - vì vậy tôi nghĩ rằng "đây là cách thực hiện trong Java" được chấp nhận hơn thế này. Về mặt kỹ thuật, bạn có thể làm bất cứ điều gì bạn muốn trong Python. Đó là lý do tại sao nó vừa tuyệt vời vừa khủng khiếp. Sử dụng tạm thời là một thói quen xấu.
Michael Tamvel

0

Nếu bạn thử nó trong Anaconda trên Windows, PyPDF2 có thể không xử lý một số tệp PDF có cấu trúc không chuẩn hoặc ký tự unicode. Tôi khuyên bạn nên sử dụng đoạn mã sau nếu bạn cần mở và đọc nhiều tệp pdf - văn bản của tất cả các tệp pdf trong thư mục có đường dẫn tương đối .//pdfs//sẽ được lưu trong danh sách pdf_text_list.

from tika import parser
import glob

def read_pdf(filename):
    text = parser.from_file(filename)
    return(text)


all_files = glob.glob(".\\pdfs\\*.pdf")
pdf_text_list=[]
for i,file in enumerate(all_files):
    text=read_pdf(file)
    pdf_text_list.append(text['content'])

print(pdf_text_list)

-1

PyPDF2 không hoạt động, nhưng kết quả có thể khác nhau. Tôi đang thấy những phát hiện khá không nhất quán từ trích xuất kết quả của nó.

reader=PyPDF2.pdf.PdfFileReader(self._path)
eachPageText=[]
for i in range(0,reader.getNumPages()):
    pageText=reader.getPage(i).extractText()
    print(pageText)
    eachPageText.append(pageText)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.