[PYTHON] Wählen Sie PDFMiner, um Textinformationen aus PDF zu extrahieren

So extrahieren Sie Textinformationen aus PDF

Umgebung

Dockerfile


FROM python:3.6
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8  
RUN apt-get -y update && \
    apt-get install -y --fix-missing \
    build-essential \
    software-properties-common \
    poppler-utils && \
    apt-get clean && \
    rm -rf /tmp/* /var/tmp/* && \
    mkdir /api
WORKDIR /api
COPY requirements.txt /api/requirements.txt
RUN pip3 install --upgrade pip && \
    pip3 install --upgrade -r requirements.txt
EXPOSE 8888
ENTRYPOINT jupyter notebook --ip=0.0.0.0 --allow-root --no-browser

requirements.txt


pandas==0.24.2
pillow==7.0.0
opencv-python==3.4.2.16
pdfminer==20191125
jupyter==1.0.0
$ docker build -t pdfminer -f ./Dockerfile .
$ docker run -it -v `pwd`:/api -p 8888:8888 --name pdfminer pdfminer bash

Extrahieren Sie Textinformationen aus PDF

Wenn der Container erfolgreich erstellt wurde, wird Jupiter automatisch gestartet. Erstellen Sie daher eine Python-Datei. Die folgenden Einstellungen sind der Code, um mindestens Zeicheninformationen zu extrahieren und in einer Textdatei zu speichern. Dieses Mal ist das PDF der Financial Services Agency test.pdf. https://www.fsa.go.jp/news/30/wp/supervisory_approaches_revised.pdf

test.py


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

def pdfminer_config(line_overlap, word_margin, char_margin,line_margin, detect_vertical):
    laparams = LAParams(line_overlap=line_overlap,
                        word_margin=word_margin,
                        char_margin=char_margin,
                        line_margin=line_margin,
                        detect_vertical=detect_vertical)
    resource_manager = PDFResourceManager()
    device = PDFPageAggregator(resource_manager, laparams=laparams)
    interpreter = PDFPageInterpreter(resource_manager, device)
    return (interpreter, device)

def find_textboxes(layout_obj):
    if isinstance(layout_obj, LTTextBox):
        return [layout_obj]
    if isinstance(layout_obj, LTContainer):
        boxes = []
        for child in layout_obj:
            boxes.extend(find_textboxes(child))
        return boxes
    return []

def find_textlines(layout_obj):
    if isinstance(layout_obj, LTTextLine):
        return [layout_obj]
    if isinstance(layout_obj, LTTextBox):
        lines = []
        for child in layout_obj:
            lines.extend(find_textlines(child))
        return lines
    return []

def find_characters(layout_obj):
    if isinstance(layout_obj, LTChar):
        return [layout_obj]
    if isinstance(layout_obj, LTTextLine):
        characters = []
        for child in layout_obj:
            characters.extend(find_characters(child))
        return characters
    return []

def write_text(text_file, text):
    text_file.write(text)

text_file = open('output.txt', 'w')
with open("./test.pdf", 'rb') as f:
    interpreter, device = pdfminer_config(line_overlap=0.5, word_margin=0.1, char_margin=2, line_margin=0.5, detect_vertical=True)
    for page in PDFPage.get_pages(f):
        interpreter.process_page(page)  #Verarbeiten Sie die Seite.
        layout = device.get_result()  #Holen Sie sich das LTPage-Objekt.
        boxes = find_textboxes(layout)
        for box in boxes:
            write_text(text_file, box.get_text().strip())
        
text_file.close()

Einstellung durch Laparame

Wenn Sie nicht den gewünschten Text erhalten, passen Sie die Parameter in Laparams an. Durch Ändern von char_margin, word_margin, line_margin ändern sich die gruppierten Zeichen. Setzen Sie detect_vertivcal auf True, wenn vertikale Sätze wie Japanisch vorhanden sind.

test.py


interpreter, device = pdfminer_config(line_overlap=0.5, word_margin=0.1, char_margin=2.0, line_margin=0.5, detect_vertical=False)

スクリーンショット 2020-01-18 11.53.36.png

Inhalt der Kartons

Die im obigen Code verfügbaren Felder enthalten viele Informationen.

print(boxes[0])
# >> <LTTextBoxHorizontal(0) 92.160,755.000,524.296,766.952 'In der Vergangenheit tauschte die internationale Abteilung der Financial Services Agency jedoch Informationen aus, um die Belastung durch die Einführung internationaler Vorschriften so gering wie möglich zu halten.\n'>
print(boxes[0].get_text())
# >>In der Vergangenheit tauschte die internationale Abteilung der Financial Services Agency jedoch Informationen aus, um die Belastung durch die Einführung internationaler Vorschriften so gering wie möglich zu halten.
print(boxes[0].bbox)
# >> (92.15997480600001, 754.9998879965001, 524.2961793060001, 766.9523361965001)
# >>Im Inneren des Taple(x0, y0, x1, y1)Die Reihenfolge ist wie im Bild gezeigt.

スクリーンショット 2020-01-18 11.46.08.png

Inhalt der Zeilen

LTTextLines werden im Feld aufgelistet. Holen wir uns also die LTTextLine mit find_textline, die wir im obigen Code nicht verwendet haben.

test.py


lines = find_textlines(boxes[0])
print(lines[0])
# >><LTTextLineHorizontal 92.160,755.000,524.296,766.952 'In der Vergangenheit tauschte die internationale Abteilung der Financial Services Agency jedoch Informationen aus, um die Belastung durch die Einführung internationaler Vorschriften so gering wie möglich zu halten.\n'>
print(lines[0].get_text())
# >>In der Vergangenheit tauschte die internationale Abteilung der Financial Services Agency jedoch Informationen aus, um die Belastung durch die Einführung internationaler Vorschriften so gering wie möglich zu halten.
print(lines[0].bbox)
# >> (92.15997480600001, 754.9998879965001, 524.2961793060001, 766.9523361965001)

Inhalt der Zeichen

Darüber hinaus ist LTChar in den Zeilen aufgeführt. Neben Zeichen- und Positionsinformationen sind auch Schriftarten darin gepackt.

test.py


characters = find_characters(lines[0])
print(characters[0])
# >><LTChar 92.160,755.000,104.160,766.952 matrix=[12.00,0.00,0.00,12.00, (92.16,756.68)] font='AHTYXM+MS-PGothic' adv=1.0 text='Oder'>
print(characters[0].get_text())
# >>Oder
print(characters[0].bbox)
# >> (92.15997480600001, 754.9998879965001, 104.16042480600001, 766.9523361965001)

Wenn ich Zeit habe, möchte ich Ihnen vorstellen, wie Sie die Farbe des erworbenen Teils ändern können.

Recommended Posts

Wählen Sie PDFMiner, um Textinformationen aus PDF zu extrahieren
Extrahieren Sie japanischen Text aus PDF mit PDFMiner
Konvertierung von pdf nach txt 1 [pdfminer]
Konvertierung von pdf nach txt 2 [pyocr]
Extrahieren Sie mit Python Text aus Bildern
Konvertieren Sie eine große Anzahl von PDF-Dateien mit pdfminer in Textdateien
Extrahieren Sie Text aus [python] pdf und lesen Sie Zeichen mit Open-Jtalk vor
Konvertieren Sie an E-Mails angehängte PDF-Dateien in das Textformat
Ist es möglich, die Profilinformationen der Person aus dem Chat-Protokoll zu extrahieren?
So extrahieren Sie den Koeffizienten aus der Minutenformel
[Python] Fortsetzung - Konvertieren Sie PDF-Text Seite für Seite in CSV
Ich habe versucht, verschiedene Informationen von Remote-PC aus Python von WMI Library zu extrahieren
Extrahieren Sie Bilder und Tabellen mit Python aus PDF, um die Berichtslast zu verringern
Summe von 1 bis 10
Mit matplotlib erstellte Bilder werden von dvi nach pdf verschoben
[Python] Konvertiert PDF-Text für jede Seite in CSV (2/24 Postscript)
[Python] Ändern Sie die Standardeingabe von der Tastatur in eine Textdatei
Weitergabe vertraulicher Informationen von SSM an ECS mit CloudFormation
Ermöglicht die Auswahl nach Namen aus dem Django-Benutzernamen