Wie extrahiere ich Text aus einer PDF-Datei?

185

Ich versuche, den in dieser PDF-Datei enthaltenen Text mit zu extrahieren Python.

Ich verwende das PyPDF2- Modul und habe das folgende Skript:

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

Wenn ich den Code ausführe, erhalte ich die folgende Ausgabe, die sich von der im PDF-Dokument enthaltenen unterscheidet:

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

Wie kann ich den Text wie im PDF-Dokument extrahieren?

Einfachheit
quelle
9
Ich habe dieses Modul noch nie verwendet, aber macht es einen Unterschied, wenn Sie die Datei im Binärmodus öffnen : pdf_file = open('sample.pdf', 'rb')?
PM 2Ring
2
Danke für deine Antwort. Ich habe das mit dem Binärmodus versucht, aber nichts hat sich geändert
Einfachheit
3
Kopieren Sie den Text mit einem guten PDF-Viewer - wenn möglich mit dem kanonischen Acrobat Reader von Adobe. Erhalten Sie das gleiche Ergebnis? Der Unterschied besteht nicht darin, dass der Text unterschiedlich ist, sondern in der Schriftart - die Zeichencodes werden anderen Werten zugeordnet. Nicht alle PDFs enthalten die richtigen Daten, um dies wiederherzustellen.
usr2564301
2
Diese PDF-Datei enthält eine CMap-Zeichentabelle. Daher sind die in diesem Thread beschriebenen Einschränkungen und Problemumgehungen relevant - stackoverflow.com/questions/4203414/… .
Krieg am
1
Das PDF enthält in der Tat einen korrekten CMAP, so dass es trivial ist, die Ad-hoc-Zeichenzuordnung in einfachen Text umzuwandeln. Es ist jedoch eine zusätzliche Verarbeitung erforderlich , um die richtige Textreihenfolge abzurufen . Der Quarz-PDF-Renderer von Mac OS X ist eine unangenehme Arbeit! In der ursprünglichen Renderreihenfolge erhalte ich "m T'h iuss iisn ga tosam fopllloew DalFo dnogc wumithe ntht eI tutorial" ... Erst nach dem Sortieren nach x-Koordinaten erhalte ich ein weitaus wahrscheinlicheres korrektes Ergebnis: "Dies ist ein Beispiel-PDF-Dokument I. Ich verwende, um dem Tutorial zu folgen. "
usr2564301

Antworten:

195

Ich suchte nach einer einfachen Lösung für Python 3.x und Windows. Es scheint keine Unterstützung durch Text zu geben , was unglücklich ist, aber wenn Sie nach einer einfachen Lösung für Windows / Python 3 suchen, schauen Sie sich das Tika- Paket an, um PDFs einfach zu lesen.

Tika-Python ist eine Python-Bindung zu den Apache Tika ™ REST-Diensten, mit der Tika in der Python-Community nativ aufgerufen werden kann.

from tika import parser # pip install tika

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

Beachten Sie, dass Tika in Java geschrieben ist, sodass eine Java-Laufzeit installiert sein muss

DJK
quelle
15
Ich habe pypdf2, tika getestet und versucht, textract und pdftotext zu installieren. Pypdf2 hat 99 Wörter zurückgegeben, während Tika alle 858 Wörter von meiner Testrechnung zurückgegeben hat. Also ging ich mit Tika.
Stian
8
Mann, ich liebe dich. Ich weiß nicht, warum eine so gute Antwort in StackOverflow versteckt ist. Alle erwähnen immer wieder, dass wir PyPDF2 oder pdfminer verwenden müssen, aber sie stinken. Ich bin jetzt in Tika verliebt
jxpython
15
Ich erhalte immer wieder den Fehler "RuntimeError: Tika-Server kann nicht gestartet werden".
Nav
4
Wenn Sie dies für alle PDF-Dateien in einem Verzeichnis (rekursiv) ausführen müssen, nehmen Sie dieses Skript
Hope
3
Für brew
diejenigen
58

Verwenden Sie Textract.

Es unterstützt viele Arten von Dateien, einschließlich PDFs

import textract
text = textract.process("path/to/file.extension")
Jakobovski
quelle
24
Textwrap scheint ein netter Wrapper zu sein, stützt sich jedoch auf zahlreiche Nicht-Python-Dienstprogramme, die auf einem bestimmten System möglicherweise nicht einfach verfügbar sind.
David Brown
1
Funktioniert für PDFs, Epubs usw. - verarbeitet PDFs, bei denen selbst PDFMiner fehlschlägt.
Ulad Kasach
Wie man es in aws lambda benutzt, habe ich versucht, aber es ist ein Importfehler für textract aufgetreten
Arun Kumar
5
textractist ein Wrapper für Poppler:pdftotext(unter anderem).
Onewhaleid
1
@ArunKumar: Um in AWS Lambda etwas zu verwenden, das nicht integriert ist, müssen Sie es und alle zusätzlichen Abhängigkeiten in Ihr Bundle aufnehmen.
Jeff Learman
50

Schauen Sie sich diesen Code an:

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

Die Ausgabe ist:

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

Verwenden des gleichen Codes zum Lesen eines PDFs aus 201308FCR.pdf. Die Ausgabe ist normal.

Die Dokumentation erklärt, warum:

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.
    """
Quinn
quelle
@VineeshTP: Bekommst du etwas für page_content? Wenn ja, dann sehen Sie, ob es hilft, indem Sie eine andere Codierung als (utf-8) verwenden
Quinn
Die beste Bibliothek, die ich zum Lesen des PDF mit Python gefunden habe, ist 'tika'
Vineesh TP
201308FCR.pdf nicht gefunden.
Chaitanya Bapat
30

Nachdem ich Textract (das zu viele Abhängigkeiten zu haben schien) und pypdf2 (das keinen Text aus den von mir getesteten PDFs extrahieren konnte) und Tika (das zu langsam war) pdftotextausprobiert hatte, verwendete ich schließlich xpdf (wie bereits in einer anderen Antwort vorgeschlagen) und Ich habe gerade die Binärdatei von Python direkt aufgerufen (möglicherweise müssen Sie den Pfad an pdftotext anpassen):

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

Es gibt pdftotext, der im Grunde das Gleiche tut, aber dies setzt pdftotext in / usr / local / bin voraus, während ich dies in AWS lambda verwende und es aus dem aktuellen Verzeichnis verwenden wollte.

Übrigens: Um dies für Lambda zu verwenden, müssen Sie die Binärdatei und die Abhängigkeit von libstdc++.soin Ihre Lambda-Funktion einfügen. Ich persönlich musste xpdf kompilieren. Da Anweisungen dazu diese Antwort in die Luft jagen würden, habe ich sie in meinen persönlichen Blog gestellt .

hansaplast
quelle
4
Oh mein Gott, es funktioniert !! Endlich eine Lösung, die den Text in der richtigen Reihenfolge extrahiert! Ich möchte dich für diese Antwort umarmen! (Oder wenn Sie keine Umarmungen mögen, hier ist ein virtueller Kaffee / Bier / ...)
DonQuiKong
4
froh, dass es geholfen hat! Upvoting gibt das gleiche Gefühl wie Umarmen, also geht es mir gut!
Hansaplast
einfach ... gr8 out of box denken!
Shantanu Pathak
10

Möglicherweise möchten Sie stattdessen bewährtes xPDF und abgeleitete Tools verwenden, um Text zu extrahieren, da pyPDF2 immer noch verschiedene Probleme mit der Textextraktion zu haben scheint .

Die lange Antwort lautet, dass es viele Variationen gibt, wie ein Text in PDF codiert wird, und dass möglicherweise eine PDF-Zeichenfolge selbst dekodiert werden muss, dann eine Zuordnung mit CMAP erforderlich sein muss und dann möglicherweise die Entfernung zwischen Wörtern und Buchstaben usw. analysiert werden muss.

Wenn das PDF beschädigt ist (dh der richtige Text angezeigt wird, aber beim Kopieren Müll entsteht) und Sie wirklich Text extrahieren müssen, sollten Sie in Betracht ziehen, PDF in ein Bild zu konvertieren (mit ImageMagik ) und dann Tesseract verwenden , um Text aus dem Bild abzurufen mit OCR.

Eugene
quelle
-1, weil das OP nach dem Lesen von pdfs in Python fragt und obwohl es einen xpdf-Wrapper für Python gibt, wird dieser schlecht gepflegt.
CDuguet
9

Ich habe viele Python PDF-Konverter ausprobiert und möchte diese Bewertung aktualisieren. Tika ist eine der besten. Aber PyMuPDF ist eine gute Nachricht von @ehsaneha Benutzer.

Ich habe einen Code erstellt, um sie zu vergleichen: https://github.com/erfelipe/PDFtextExtraction Ich hoffe, Ihnen helfen zu können.

Tika-Python ist eine Python-Bindung zu den Apache Tika ™ REST-Diensten, mit der Tika in der Python-Community nativ aufgerufen werden kann.

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 )
erfelipe
quelle
3
Besonderer Dank für.encode('utf-8', errors='ignore')
Evgeny
AttributeError: Modul 'os' hat kein Attribut 'setsid'
keramat
7

Der folgende Code ist eine Lösung für die Frage in Python 3 . Stellen Sie vor dem Ausführen des Codes sicher, dass Sie die PyPDF2Bibliothek in Ihrer Umgebung installiert haben . Wenn nicht installiert, öffnen Sie die Eingabeaufforderung und führen Sie den folgenden Befehl aus:

pip3 install PyPDF2

Lösungscode:

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())
Steffi Keran Rani J.
quelle
2
Wie würden Sie den gesamten Inhalt in einer Textdatei speichern und für die weitere Analyse verwenden
Rahul Agarwal
7
Dies löst das in der eigentlichen Frage erwähnte Problem nicht.
Soumik Rakshit
7

PyPDF2 ignoriert in einigen Fällen die Leerzeichen und macht den Ergebnistext zu einem Chaos, aber ich verwende PyMuPDF und bin sehr zufrieden, dass Sie diesen Link für weitere Informationen verwenden können

ehsaneha
quelle
pymupdf ist die beste Lösung, die ich beobachtet habe, erfordert keine zusätzlichen C ++ - Bibliotheken wie pdftotext oder Java wie tika
Kay
pymypdf ist wirklich die beste Lösung, kein zusätzlicher Server oder Bibliotheken, und es funktioniert mit Dateien, in denen PyPDF2 PypDF3 PyPDF4 leere Textzeichenfolgen abruft. Danke vielmals!
Andrea Bisello
Um pymupdf zu installieren, führen Sie aus pip install pymupdf==1.16.16. Verwendung dieser speziellen Version, da heute die neueste Version (17) nicht funktioniert. Ich habe mich für pymupdf entschieden, weil es Textumbruchfelder in neuen Zeilenzeichen extrahiert \n. Also extrahiere ich den Text aus pdf in eine Zeichenfolge mit pymupdf und verwende ihn dann my_extracted_text.splitlines(), um den Text in Zeilen in eine Liste aufzuteilen .
Erickfis
PyMuPDF war wirklich überraschend. Vielen Dank.
erfelipe
5

Mehrseitiges PDF kann als Text auf einer Strecke extrahiert werden, anstatt die individuelle Seitenzahl als Argument unter Verwendung des folgenden Codes anzugeben

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')
Yogi
quelle
Einziges Problem hier ist, dass der Inhalt der neuen Seite die letzte überschreibt
Rahul Agarwal
5

pdftotext ist der beste und einfachste! pdftotext behält sich auch die Struktur vor.

Ich habe PyPDF2, PDFMiner und einige andere ausprobiert, aber keiner von ihnen ergab ein zufriedenstellendes Ergebnis.

Dharam
quelle
Meldung wie folgt bei der Installation von pdf2text, Collecting PDFMiner (from pdf2text)daher verstehe ich diese Antwort jetzt nicht.
Zhy
pdf2text und pdftotext sind unterschiedlich. Sie können den Link aus der Antwort verwenden.
Dharam
OK. Das ist ein bisschen verwirrend.
Zhy
3

Hier ist der einfachste Code zum Extrahieren von Text

Code:

# 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()
Unendlichkeit
quelle
Empfehlende 'Tika'
Vineesh TP
2

Ich habe hier eine Lösung gefunden PDFLayoutTextStripper

Es ist gut, weil es das Layout der Original-PDF beibehalten kann .

Es ist in Java geschrieben, aber ich habe ein Gateway hinzugefügt, um Python zu unterstützen.

Beispielcode:

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

Beispielausgabe von PDFLayoutTextStripper : Geben Sie hier die Bildbeschreibung ein

Weitere Details finden Sie hier Stripper mit Python

Tho
quelle
1

Verwenden Sie zum Extrahieren von Text aus PDF den folgenden Code

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

pdfReader = PyPDF2.PdfFileReader(pdfFileObj)

print(pdfReader.numPages)

pageObj = pdfReader.getPage(0)

a = pageObj.extractText()

print(a)
Elavarasan r
quelle
1

Ich habe eine bessere Lösung als OCR und die Seitenausrichtung beizubehalten, während der Text aus einer PDF-Datei extrahiert wird. Sollte hilfreich sein:

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)
Anit Chakraborty
quelle
0

Ich füge Code hinzu, um dies zu erreichen: Es funktioniert gut für mich:

# 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)
Ritesh Shanker
quelle
0

Sie können tika-app-xxx.jar (aktuell) von hier herunterladen .

Legen Sie diese JAR-Datei dann im selben Ordner wie Ihre Python-Skriptdatei ab.

Fügen Sie dann den folgenden Code in das Skript ein:

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

Der Vorteil dieser Methode:

weniger Abhängigkeit. Eine einzelne JAR-Datei ist einfacher zu verwalten als ein Python-Paket.

Unterstützung für mehrere Formate. Die Position source_pdfkann das Verzeichnis jeder Art von Dokument sein. (.doc, .html, .odt usw.)

auf dem neuesten Stand. tika-app.jar wird immer früher als die entsprechende Version des tika python-Pakets veröffentlicht.

stabil. Es ist weitaus stabiler und gepflegter (Powered by Apache) als PyPDF.

Nachteil:

Ein Jre-Headless ist notwendig.

pah8J
quelle
total keine pythonische Lösung. Wenn Sie dies empfehlen, sollten Sie ein Python-Paket erstellen und die Leute das importieren lassen. Es wird nicht empfohlen, Befehlszeilenausführungen von Java-Code in Python zu verwenden.
Michael Tamillow
@ MichaelTamillow, wenn ich einen Code schreibe, der in pypi hochgeladen werden soll, gebe ich zu, dass dies keine gute Idee ist. Wenn es sich jedoch nur um ein Python-Skript mit Shebang zur vorübergehenden Verwendung handelt, ist es nicht schlecht, nicht wahr?
pah8J
Nun, die Frage trägt nicht den Titel "Python" - daher denke ich, dass es akzeptabler ist, "hier ist, wie man es in Java macht" zu sagen. Technisch können Sie in Python alles tun, was Sie wollen. Deshalb ist es sowohl großartig als auch schrecklich. Vorübergehende Nutzung ist eine schlechte Angewohnheit.
Michael Tamillow
0

Wenn Sie es in Anaconda unter Windows versuchen, verarbeitet PyPDF2 möglicherweise einige der PDF-Dateien mit nicht standardmäßigen Strukturen oder Unicode-Zeichen nicht. Ich empfehle die Verwendung des folgenden Codes, wenn Sie viele PDF-Dateien öffnen und lesen müssen - der Text aller PDF-Dateien in Ordnern mit relativem Pfad .//pdfs//wird in der Liste gespeichert 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)
DovaX
quelle
-1

PyPDF2 funktioniert, aber die Ergebnisse können variieren. Ich sehe ziemlich inkonsistente Ergebnisse aus der Ergebnisextraktion.

reader=PyPDF2.pdf.PdfFileReader(self._path)
eachPageText=[]
for i in range(0,reader.getNumPages()):
    pageText=reader.getPage(i).extractText()
    print(pageText)
    eachPageText.append(pageText)
bmc
quelle