[PYTHON] Lassen Sie uns überlegen, ob es sich um eine PDF- und eine Ausnahmeverarbeitung handelt. Bis Sie Ihre eigene Ausnahmeverarbeitung erstellen

"Erstellen eines Dienstes, der den Nutzungsverlauf von Suica für Mobilgeräte so bearbeitet, dass er problemlos zur Kostenabrechnung verwendet werden kann" Mobile Suica-Nutzungsverlaufs-PDF mit tabula-py in das Pandas DataFrame-Format umwandeln Klicken Sie hier für das fertige Produkt https://www.mobilesuica.work

Fehlerbehandlung

Die Fehlerbehandlung ist eine hohe Schwelle für Amateure wie den Autor. Dies ist schwierig, da es im Vorgriff auf auftretende Ausnahmen und fehlerhafte Vorgänge des Benutzers erfolgt (obwohl dies natürlich in den Testergebnissen hinzugefügt wird).

Die folgenden zwei Fehlerbehandlungen werden diesmal berücksichtigt.

--Wenn das PDF, das Sie an tabula-py übergeben, falsch ist

Als Ergebnis des Blicks auf die unten stehenden Links und andere Seiten hielt ich es für richtig, die Ausnahme mit try-exception abzufangen und mit raise zu erhöhen. Die meisten Dinge, die Sie auf GitHub lernen, sind so. * So implementieren Sie eine Fehlerbenachrichtigung im Python-Programm

Beurteilung, ob es sich um PDF handelt

Ich habe eine praktische gefunden, die [** PyPDF2 **] heißt (https://pythonhosted.org/PyPDF2/).

test.py


import PyPDF2
with open('a.pdf','rb') as f:
    pageNum = PyPDF2.PdfFileReader(f).getNumPages()
    print(f"Die Anzahl der Seiten{pageNum}ist")

Ausführungsergebnis

(app-root) bash-4.2# python3 test.py
Die Anzahl der Seiten beträgt 2

Wenn Sie eine Nicht-PDF-Datei übergeben, sieht diese folgendermaßen aus

test.py


fileList = ['a.pdf','test.py']
for fileName in fileList:
    with open(fileName,'rb') as f:
        pageNum = PyPDF2.PdfFileReader(f).getNumPages()
        print(f"{fileName}Die Anzahl der Seiten ist{pageNum}ist")

Ausführungsergebnis

(app-root) bash-4.2# python3 test.py
a.Die Anzahl der Seiten im PDF beträgt 2
Traceback (most recent call last):
  File "test.py", line 9, in <module>
    pageNum = PyPDF2.PdfFileReader(f).getNumPages()
  File "/opt/app-root/lib/python3.6/site-packages/PyPDF2/pdf.py", line 1084, in __init__
    self.read(stream)
  File "/opt/app-root/lib/python3.6/site-packages/PyPDF2/pdf.py", line 1696, in read
    raise utils.PdfReadError("EOF marker not found")
PyPDF2.utils.PdfReadError: EOF marker not found

** PyPDF2.utils.PdfReadError: EOF-Marker nicht gefunden ** scheint eine Ausnahme zu sein, die PyPDF2 auslöst, wenn es sich nicht um eine PDF-Datei handelt. Die Nachricht scheint sich abhängig von der übergebenen Datei zu ändern, und es gab auch ** Fehlerhafte PDF-Datei konnte nicht gelesen werden **. In jedem Fall wird das Programm hier gestoppt, wenn Sie diese Ausnahme nicht gut behandeln.

Ausnahmebehandlung

Vorerst wäre es schön, ** PyPDF2.utils.PdfReadError ** abholen zu können.

test.py


try:
    fileList = ['a.pdf','test.py']
    for fileName in fileList:
        with open(fileName,'rb') as f:
            pageNum = PyPDF2.PdfFileReader(f).getNumPages()
            print(f"{fileName}Die Anzahl der Seiten ist{pageNum}ist")
except PyPDF2.utils.PdfReadError as e:
    print(f"ERROR: {e}PDF ist falsch")

Ausführungsergebnis

(app-root) bash-4.2# python3 test.py
a.Die Anzahl der Seiten im PDF beträgt 2
ERROR:EOF-Marker nicht gefunden PDF ist falsch

Selbst wenn eine Ausnahme auftritt, kann die Verarbeitung fortgesetzt werden. Letztendlich können Sie den Benutzer benachrichtigen, der die Nicht-PDF-Datei hochgeladen hat.

Es gibt jedoch eine Unannehmlichkeit, wie es ist. Da es kein Traceback gibt, wissen Sie später nicht, wo das Programm im Quellcode gestoppt wurde. Die Lösung ist einfach: Verwenden Sie einfach ein Modul namens ** traceback **.

test.py


import traceback
#...Kürzung
except PyPDF2.utils.PdfReadError as e:
    print(f"ERROR: {e}PDF ist falsch")
    traceback.print_exc() 

Ausführungsergebnis

(app-root) bash-4.2# python3 test.py
a.Die Anzahl der Seiten im PDF beträgt 2
ERROR:EOF-Marker nicht gefunden PDF ist falsch
Traceback (most recent call last):
  File "test.py", line 10, in <module>
    pageNum = PyPDF2.PdfFileReader(f).getNumPages()
  File "/opt/app-root/lib/python3.6/site-packages/PyPDF2/pdf.py", line 1084, in __init__
    self.read(stream)
  File "/opt/app-root/lib/python3.6/site-packages/PyPDF2/pdf.py", line 1696, in read
    raise utils.PdfReadError("EOF marker not found")
PyPDF2.utils.PdfReadError: EOF marker not found

Sie können sehen, dass der Traceback anders als der vorherige ist.

Wenn man sich den Quellcode anderer Leute ansieht, heißt es ** außer Ausnahme als e: **, also nehme ich alle Ausnahmen auf. Dies scheint als Basisklasse bezeichnet zu werden. Wenn Sie nach dem Lesen verschiedener Dinge die Verarbeitung abhängig von der von Ihnen aufgenommenen Ausnahme ändern möchten, geben Sie an, welche Ausnahme ** PyPDF2.utils.PdfReadError ** ist, andernfalls, wenn die Verarbeitung dieselbe ist ** mit Ausnahme von Ausnahme wie e: * * Aber es sieht gut aus. Ist es zum Beispiel so?

test.py


try:
    fileList = ['test.py']
    for fileName in fileList:
        with open(fileName,'rb') as f:
            pageNum = PyPDF2.PdfFileReader(f).getNumPages()
            print(f"{fileName}Die Anzahl der Seiten ist{pageNum}ist")
            df = tabula.read_pdf(fileName,pages='all',pandas_options={'dtype':'object'})
except PyPDF2.utils.PdfReadError as e:
    print(f"ERROR: {e}PDF ist falsch")
except Exception as e:
    print(f"ERROR: {e}Irgendwas stimmt nicht")

Übrigens, wenn Sie die Basisklasse zuerst schreiben, wird sie dort in die Verarbeitungsroute eingegeben. Versuchen Sie also, die Basisklasse zuletzt zu schreiben.

Fehlerbehandlung mit tabula-py

Es gibt keine Ausnahmen für die Angabe einer nicht tabellarischen PDF-Datei. Sie müssen also nur sicherstellen, dass es sich nicht um eine mobile Suica-PDF-Datei handelt. Lesen Sie zuerst den DataFrame-Header. Ich habe eine leere Datei (blank.pdf) als falsches PDF vorbereitet.

test.py


fileList = ['a.pdf','blank.pdf']
for fileName in fileList:
    df = tabula.read_pdf(fileName,pages='all',pandas_options={'dtype':'object'})
    h = df[0].columns.values.tolist()
    print(f"Der Header ist{h}ist")

Ausführungsergebnis

(app-root) bash-4.2# python3 test.py
Der Header ist['Mond', 'Tag', 'Art', 'Station benutzt', 'Art.1', 'Station benutzt.1', 'Balance', 'Unterschied']ist
Traceback (most recent call last):
  File "test.py", line 11, in <module>
    h = df[0].columns.values.tolist()
IndexError: list index out of range

Anscheinend gibt es einen Indexfehler, also ist dies eine Ausnahme. Als weitere Fehlerbehandlung ist es möglich, dass der DataFrame-Header entfernt wurde, aber eine tabellarische PDF-Datei, die sich von der Mobile Suica-PDF-Datei unterscheidet, hochgeladen wurde. Wenn Sie den Inhalt des Headers überprüfen, wird er angezeigt, scheint jedoch einen anderen Fehler zu verursachen. Beenden Sie daher die Fehlerbehandlung bis zu diesem Punkt. Das Programm, das schließlich die Liste der vom Benutzer hochgeladenen Dateien als Dateiliste empfängt und verarbeitet, ist wie folgt.

test.py


import tabula
import PyPDF2
import traceback
import pandas as pd

try:
    fileList = ['a.pdf','blank.pdf']
    dfList = []
    for fileName in fileList:
        with open(fileName,'rb') as f:
            pageNum = PyPDF2.PdfFileReader(f).getNumPages()
            df = tabula.read_pdf(fileName,pages='all',pandas_options={'dtype':'object'})
            if df[0].columns.values.tolist():
                for i in range(len(df)):
                    dfList.append(df[i])
                print(f"{fileName}Konnte korrekt verarbeitet werden")
    d = pd.concat(dfList,ignore_index=True)
    
except PyPDF2.utils.PdfReadError as e:
    print(f"ERROR: {e} {fileName}Scheint nicht in PDF zu sein")
    traceback.print_exc() 
except IndexError as e:
    print(f"ERROR: {e} {fileName}Ist ein PDF, aber es scheint kein mobiles Suica PDF zu sein")
    traceback.print_exc() 
except Exception as e:
    print(f"ERROR: {e} {fileName}Irgendwas stimmt nicht")
    traceback.print_exc() 

Ausführungsergebnis

(app-root) bash-4.2# python3 test.py
a.pdf wurde korrekt verarbeitet
ERROR: list index out of range blank.pdf ist ein PDF, aber es scheint kein mobiles Suica PDF zu sein
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    if df[0].columns.values.tolist():
IndexError: list index out of range

Selbst erstellte Ausnahmebehandlung

Da die Verarbeitung bis zu diesem Punkt als Funktion aufgerufen wird, erscheint die Fehlermeldung nur im Serverprotokoll und ist für den Benutzer nicht sichtbar. Diese Fehlermeldung muss an den Anrufer zurückgegeben werden, damit sie für den Benutzer sichtbar ist. Wenn Sie es erneut senden, wie es mit ** erhöhen ** ist, wird nur die ursprüngliche Fehlermeldung gesendet. Wenn es zu einer Funktion gemacht wird, sieht es so aus

test.py


def test():
    try:
        fileList = ['copy.sh']
        dfList = []
        for fileName in fileList:
            with open(fileName,'rb') as f:
                pageNum = PyPDF2.PdfFileReader(f).getNumPages()
                df = tabula.read_pdf(fileName,pages='all',pandas_options={'dtype':'object'})
                if df[0].columns.values.tolist():
                    for i in range(len(df)):
                        dfList.append(df[i])
                    print(f"{fileName}Konnte korrekt verarbeitet werden")
        d = pd.concat(dfList,ignore_index=True)
        print(d)
        
    except PyPDF2.utils.PdfReadError as e:
        print(f"ERROR: {e} {fileName}Scheint nicht im PDF-Test zu sein()im")
        raise
    except IndexError as e:
        print(f"ERROR: {e} {fileName}Ist ein PDF, aber es scheint kein mobiles Suica PDF zu sein")
    except Exception as e:
        print(f"ERROR: {e} {fileName}Irgendwas stimmt nicht")

try:
    test()
except Exception as e:
    print(f"{e}Anrufer")

Ausführungsergebnis

(app-root) bash-4.2# python3 test.py
ERROR: Could not read malformed PDF file copy.sh scheint nicht im PDF-Test zu sein()im
Fehlerhafte PDF-Datei Caller konnte nicht gelesen werden

Ich weiß nicht, welche Datei schlecht war. Die einzige Möglichkeit, dies zu lösen, bestand darin, eine Ausnahme zu machen, die etwas verbeult war, aber ich war erleichtert, dass es sich als ziemlich einfach herausstellte. Auf dieser Website finden Sie eine leicht verständliche Erklärung. Fügen Sie einfach zwei Zeilen hinzu! !! * Codebeispiel (3 Typen) zum Erstellen und Verwenden von Ausnahmen in Python

Hier ist also die mit Ihrer eigenen Ausnahmebehandlung

test.py


import tabula
import PyPDF2
import traceback
import pandas as pd

class ConvertError(Exception):
    pass

def test():
    try:
        fileList = ['copy.sh']
        dfList = []
        for fileName in fileList:
            with open(fileName,'rb') as f:
                pageNum = PyPDF2.PdfFileReader(f).getNumPages()
                df = tabula.read_pdf(fileName,pages='all',pandas_options={'dtype':'object'})
                if df[0].columns.values.tolist():
                    for i in range(len(df)):
                        dfList.append(df[i])
                    print(f"{fileName}Konnte korrekt verarbeitet werden")
        d = pd.concat(dfList,ignore_index=True)
        print(d)
        
    except PyPDF2.utils.PdfReadError as e:
        traceback.print_exc() 
        errorText =  f"ERROR: {e} {fileName}Scheint nicht in PDF zu sein=> test()im"
        print(errorText)
        raise ConvertError(errorText)
    except IndexError as e:
        traceback.print_exc()
        errorText = f"ERROR: {e} {fileName}Ist ein PDF, aber es scheint kein mobiles Suica PDF zu sein"
        print(errorText)
        raise ConvertError(errorText)
    except Exception as e:
        traceback.print_exc()  
        errorText = f"ERROR: {e} {fileName}Irgendwas stimmt nicht"
        print(errorText)
        raise ConvertError(errorText)

try:
    test()
except Exception as e:
    print(f"{e}Anrufer")

Ausführungsergebnis

(app-root) bash-4.2# python3 test.py
Traceback (most recent call last):
  File "test.py", line 15, in test
    pageNum = PyPDF2.PdfFileReader(f).getNumPages()
  File "/opt/app-root/lib/python3.6/site-packages/PyPDF2/pdf.py", line 1084, in __init__
    self.read(stream)
  File "/opt/app-root/lib/python3.6/site-packages/PyPDF2/pdf.py", line 1697, in read
    line = self.readNextEndLine(stream)
  File "/opt/app-root/lib/python3.6/site-packages/PyPDF2/pdf.py", line 1937, in readNextEndLine
    raise utils.PdfReadError("Could not read malformed PDF file")
PyPDF2.utils.PdfReadError: Could not read malformed PDF file
ERROR: Could not read malformed PDF file copy.sh scheint kein PDF zu sein=> test()im
ERROR: Could not read malformed PDF file copy.sh scheint kein PDF zu sein=> test()Im Anrufer

Recommended Posts

Lassen Sie uns überlegen, ob es sich um eine PDF- und eine Ausnahmeverarbeitung handelt. Bis Sie Ihre eigene Ausnahmeverarbeitung erstellen
Erstellen Sie Ihre eigene Ausnahme
Einführung in die Verwendung von Pytorch Lightning ~ Bis Sie Ihr eigenes Modell formatieren und auf Tensorboard ausgeben ~
Bis Sie Ihren eigenen Dolmetscher selbst hosten
Bis Sie einen Schnappschuss des Amazon Elasticsearch-Dienstes erhalten und wiederherstellen