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

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.

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