[Python] Fortsetzung - Konvertieren Sie PDF-Text Seite für Seite in CSV

Nach vorherigen dachte ich, dass diese Reparatur notwendig ist, also ist es eine einfache Fortsetzung.

Der Anfang der Sache

Es ist in Ordnung, die PDF-Seite im CSV-Format auszugeben, aber ich sagte, es handele sich um eine Menge Demo-Daten. Insbesondere kam der Untertitel in die Mitte. Es ist nüchtern und schmerzhaft.

Als ich kein ähnliches Projekt finden konnte, fand ich die folgende Seite. Analyse der Liste der schwarzen Unternehmen des Ministeriums für Gesundheit, Arbeit und Soziales mit Python (PDFMiner.six)

Ich wusste, dass ich einen Kameraden hatte und mit den Koordinaten auskommen konnte. Also werde ich es versuchen.

Überprüfung-Vorbereitung-

Referenz: Wählen Sie PDFMiner aus, um Textinformationen aus PDF zu extrahieren

Es scheint, dass pdfminer auch die Koordinateninformationen des Layouts abrufen kann. Bisher wurden mit TextConverter nur Zeichendaten extrahiert. In PDFPageAggregator scheinen Koordinaten und Zeichendaten herausgezogen zu sein. Verwenden Sie diese Option.

Überprüfen Sie vorerst, welche Koordinaten verfügbar sind. Es tut mir leid, dass ich das Beispiel-PDF nicht vorbereiten konnte ...

from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter, PDFPageAggregator
from pdfminer.layout import LAParams, LTContainer, LTTextBox, LTTextLine, LTChar
from pdfminer.pdfpage import PDFPage

def convert_pdf_to_txt(self,p_d_f):
    
    fp = open(p_d_f, 'rb')
    for page in PDFPage.get_pages(fp):
        
        rsrcmgr = PDFResourceManager()
        laparams = LAParams()
        laparams.detect_vertical = True
        device = PDFPageAggregator(rsrcmgr, laparams=laparams)
        interpreter = PDFPageInterpreter(rsrcmgr, device)
        
        #Holen Sie sich Koordinaten und Zeichendaten aus PDF
        interpreter.process_page(page)
        layout = device.get_result()
        
        #Anzeige von Koordinaten und Zeichen
        for node in layout:
            if isinstance(node, LTTextBox) or isinstance(node, LTTextLine):
                print(node.get_text())   #Brief
                word =input(node.bbox)   #Koordinate
        word =input("---page end---")

Ein ineffizienter Typ, der an der Eingabeaufforderung nachschaut.

Um ehrlich zu sein, verstehe ich das Urteil nicht wirklich wie LTTextBox, aber ich habe es als Magie eingesetzt. Lass es uns richtig herausfinden.

Prüfergebnis-

Dies ist ein Auszug aus dem Ausgabeergebnis. Der Text ist Dummy.

---page end---
Über Popcornmaschine

(68.28, 765.90036, 337.2, 779.9403599999999)
Es ist eine Maschine, die Popcorn knallt und herstellt.

(67.8, 697.71564, 410.4000000000001, 718.47564)
Bitte seien Sie vorsichtig, wenn Sie es verwenden.

(67.8, 665.29564, 339.8400000000002, 686.05564)
Die Verwendung ist wie folgt.

(67.8, 643.69564, 279.3600000000001, 653.65564000)
Erläuterung

(67.8, 730.11564, 87.96000000000001, 740.07564)

Taple ist die Koordinate. Die Reihenfolge ist (x0, y0, x1, y1). Einzelheiten finden Sie auf der Referenzseite! Einfach ausgedrückt, wenn Sie sich y1 ansehen, können Sie die Koordinaten der Zeichen von unten sehen. Mit anderen Worten, wenn y1 auf der Seite in absteigender Reihenfolge ist, werden die Zeichen in der Reihenfolge von oben angeordnet = richtige Anordnungsform (in diesem Fall).

Wenn man dieses Ausgabeergebnis betrachtet, ist y1 in der letzten Zeile das zweitgrößte, daher ist es ein irrelevantes Ergebnis unter dem Gesichtspunkt, einfach von oben anzuordnen. Es kann basierend auf x0 sortiert werden. Ich weiß nichts Es scheint, dass die Koordinaten gut genommen sind, also werde ich etwas mit diesem y1 machen.

Vorgeschlagene Lösung

① Erstellen Sie ein Wörterbuch ② Sortieren Sie das Wörterbuch (Schlüssel in absteigender Reihenfolge) ③ Machen Sie es zu einer Zeichenkette ④ Zeilenumbrüche bereinigen

Das sollte funktionieren. Wenn Sie eine schlaue Person sind, schauen Sie sich bitte nur das fertige Produkt an.

① Erstellen Sie ein Wörterbuch

d=[]
for node in layout:
    if isinstance(node, LTTextBox) or isinstance(node, LTTextLine):
        y1 = node.bbox[3]
        #Wenn es sich um eine Tabelle handelt, werden die Koordinaten von y1 dupliziert
        if y1 in d:
           d[y1] += "|" + node.get_text()
        else:
           d[y1] = node.get_text()

Erstellen Sie ein schnelles Wörterbuch mit Koordinaten und Zeichen. Ich ergreife auch Tischmaßnahmen, um mich zu entspannen.

Aber um ehrlich zu sein, ist diese Methode, es zu öffnen, eine unfruchtbare Anstrengung, weil es Löcher hat. Der Grund dafür ist, dass die obigen Koordinaten Zeichen Zeile für Zeile zu nehmen scheinen, aber der Mechanismus besteht darin, einen Randauffüllungs-ähnlichen Wert festzulegen und in naher Zukunft einen Zeichenblock als "Block" zu verwenden. Es scheint, dass es (sicherlich) ist.

Solide Geschichte: Wenn Sie nichts festlegen, wird der Standardrand angewendet und mehrere Zeilen werden als ein Block in Sätzen mit engen Zeilenabständen und feinen Tabellen erkannt. Wenn Sie also mehrere Zeichenzeilen mit denselben Koordinaten erhalten, ist dies bereits ein Zusammenbruch der Ese-Tabellenoperation.

Wenn ja, spreche ich davon, die Randauffüllung richtig einzustellen, aber diesmal habe ich nicht so viel verlangt, deshalb werde ich sie nicht besonders einstellen. Wenn der Tisch herauskommt, versuchen wir es mit dem Gefühl "Es tut mir leid!"

② Wörterbuch sortieren (absteigender Schlüssel)

Referenz: Zusammenfassung der Python-Sortierung (Liste, Wörterbuchtyp, Serie, Datenrahmen)

d2 = sorted(d.items(), key=lambda x: -x[0])

Ich habs gemacht! Ramuda Hatsuyoshi! Wenn Sie dies tun, wird das Wörterbuch übrigens eine Liste sein. Es ist mir egal, solange ich sortieren kann.

③ Machen Sie es zu einer Zeichenkette

text = ""
for d0 in d2:
     text += d0[1]

Es ist nur rund und rund.

④ Zeilenumbrüche bereinigen

Referenz: Kommagetrennte Zeichenfolgen mit Python teilen, Leerzeichen und Liste teilen, entfernen Ich bin dir immer zu Dank verpflichtet.

space = re.compile("[  ]+")
text = re.sub(space, "", text )
l_text = [a for a in text.splitlines() if a != '']
text = '\n'.join(l_text).replace('\n|', '|')

Es gibt viele Leerzeichen und Zeilenumbrüche. Dies ist eine Lösung für das Problem. Ersetzen Sie Leerzeichen und löschen Sie Zeilenumbrüche als Liste. Übrigens wird auch der Zeilenumbruch vor dem Symbol gelöscht, das bei der Rückkehr zur Tabelle als Markierung verwendet wurde.

Fertiges Produkt


from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter, PDFPageAggregator
from pdfminer.layout import LAParams, LTContainer, LTTextBox, LTTextLine, LTChar
from pdfminer.pdfpage import PDFPage

import csv,re,datetime
import pandas as pd

class converter(object):
    def convert_pdf_to_txt(self,p_d_f):
        print("system:pdf【" + p_d_f + "] Ist gelesen")
        
        df = pd.DataFrame(columns=["Datum und Uhrzeit aktualisieren","Satz","Seitennummer"])
        
        cnt = 1
        space = re.compile("[  ]+")
        fp = open(p_d_f, 'rb')
       
        #Extrahieren Sie Koordinaten und Zeichendaten aus dem PDF
        for page in PDFPage.get_pages(fp):
            rsrcmgr = PDFResourceManager()
            laparams = LAParams()
            laparams.detect_vertical = True
            device = PDFPageAggregator(rsrcmgr, laparams=laparams)
            interpreter = PDFPageInterpreter(rsrcmgr, device)
            #Holen Sie sich Koordinaten und Zeichendaten aus PDF
            interpreter.process_page(page)
            layout = device.get_result() 
            
            #Erstellen Sie ein Wörterbuch mit Koordinaten und Daten
            d={}
            for node in layout:
                if isinstance(node, LTTextBox) or isinstance(node, LTTextLine):
                    y1 = node.bbox[3]
                    #Wenn es sich um eine Tabelle handelt, werden die Koordinaten von y1 dupliziert
                    if y1 in d:
                       d[y1] += "|" + node.get_text()
                    else:
                       d.update({y1 : node.get_text()})
            
            #Nach Koordinaten sortieren
            d2 = sorted(d.items(), key=lambda x: -x[0])
            
            #Stoßen Sie gegen eine Schnur
            text = ""
            for d0 in d2:
                 text += ddd[1]
            
            #Leere Zeilenumbrüche entfernen
            text = re.sub(space, "", text)
            l_text = [a for a in text.splitlines() if a != '']
            text = '\n'.join(l_text).replace('\n|', '|')     
            
            df.loc[cnt,["Satz","Seitennummer"]] = [text,cnt]
            cnt += 1
            
        fp.close()
        device.close()
         
        now = datetime.datetime.now()
        df["Datum und Uhrzeit aktualisieren"] = now

        csv_path = p_d_f.replace('.pdf', '.csv')
        with open(csv_path, mode='w', encoding='cp932', errors='ignore', newline='\n') as f:
             df.to_csv(f,index=False)

if __name__ == "__main__":

  p_d_f = "Irgendwie.pdf"
  con=converter()
  hoge=con.pdf_to_csv(p_d_f)

Ich habe es nicht gut überprüft, weil ich es vom letzten Mal addiert und subtrahiert habe, aber etwas Ähnliches hat funktioniert. Wenn Sie einen Fehler erhalten, beheben Sie ihn bitte selbst.

Recommended Posts

[Python] Fortsetzung - Konvertieren Sie PDF-Text Seite für Seite in CSV
[Python] Konvertiert PDF-Text für jede Seite in CSV (2/24 Postscript)
So fügen Sie einer PDF-Datei Seitenzahlen hinzu (in Python)
So speichern Sie eine von Python gekratzte Tabelle in CSV
Seitenzahl zu PDF hinzufügen
Sprechen mit Python [Text zu Sprache]
Schreiben Sie mit Python in csv
Konvertieren Sie Markdown in Python in PDF
[Python] Mit Python in eine CSV-Datei schreiben
Ausgabe in eine CSV-Datei mit Python
Schließen Sie sich csv an, das von Python-Pandas normalisiert wurde, um die Überprüfung zu vereinfachen
[Good By Excel] Python-Skript zum Generieren von SQL zum Konvertieren von CSV in Tabelle
[Python] So konvertieren Sie eine Datenbankdatei in CSV
Wiedereinführung in Python-Dekoratoren ~ Lernen wir Dekoratoren nach Typ ~
Antwort auf AtCoder Beginners Selection von Python3
[Python] Konvertieren Sie CSV-Dateibegrenzer in Tabulatortrennzeichen
Funktion zum Speichern von Bildern nach Datum [python3]
Ich möchte eine in Python in PDF konvertierte Tabelle wieder in CSV konvertieren
Konvertieren Sie an E-Mails angehängte PDF-Dateien in das Textformat
Lesen Sie Python csv und exportieren Sie es nach txt
Empfohlene Bücher von 3 Typen im Zusammenhang mit Python
[Teil1] Scraping mit Python → Organisieren Sie bis zu CSV!
Python> Ausgaben von 1 bis 100, 501 bis 600> Für CSV
(Sonstige Hinweise) Datenaktualisierungsmuster von der CSV-Datenerfassung / -verarbeitung durch Python nach Excel
[Python] So zeigen Sie die Elemente der Liste nebeneinander an
Lesen einer CSV-Datei mit Python 2/3
Kratzen Sie das Essen mit Python und geben Sie es an CSV aus
Zusammenfassung des Bibliotheksvergleichs zum Generieren von PDF mit Python
Laden Sie eine Textdatei mit FTP auf den Mietserver hoch
Konvertieren Sie PDF in Bilder (JPEG / PNG) mit Python
[Python] Konvertieren von DICOM in PNG oder CSV
tse - Einführung in den Text Stream Editor in Python
Schreiben von Protokollen in eine CSV-Datei (Python, C-Sprache)
So löschen Sie die von Python ausgegebenen Zeichen
COCO'S Frühstücksbuffet Store Liste PDF konvertiert in CSV
[Python] So sortieren Sie Instanzen nach Instanzvariablen
Ich möchte die Produkte verkaufen, die ich durch Python Scraping Mercari aufgelistet habe
Führen Sie Power Query aus, indem Sie Argumente an Python übergeben
Auf Python 2.7.9 aktualisiert
CSV in Python
Python-Referenzseite
"Backport" zu Python 2
[Keras] Persönliches Memo zum Klassifizieren von Bildern nach Ordner [Python]
Liste der Beiträge zur Optimierung durch Python to Docker
Ich habe versucht, eine CSV-Datei mit Python zu berühren
Lesen Sie die XML-Datei anhand des Python-Tutorials
Konvertieren Sie das Bild in .zip mit Python in PDF
So konvertieren Sie eine JSON-Datei mit Python Pandas in eine CSV-Datei
[Python] Ändern Sie die Standardeingabe von der Tastatur in eine Textdatei
[Python] Ein Memo zum vertikalen Schreiben von CSV mit Pandas
[Python-pptx] Gibt PowerPoint-Schriftinformationen mit Python in CSV aus
Führen Sie zwei PDF-Dateien Seite für Seite zusammen
Python-Skript, das eine JSON-Datei aus einer CSV-Datei erstellt
Lesen von CSVs, die in Python nur Ganzzahlen enthalten
Python Open CV hat versucht, das Bild im Text anzuzeigen.
Lesen von Text mit Standardeingabe oder Dateinamen wie cat in Python