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