Python прочитал часть страницы PDF

Я пытаюсь прочитать файл pdf, где каждая страница разделена на блоки информации 3x3 вида

A | B | C
D | E | F
G | H | I

Каждая запись разбита на несколько строк. Упрощенным примером одной записи является эта карточка. Но тогда были бы аналогичные записи и в других 8 слотах.

Я просмотрел pdfminer и pypdf2. Я не нашел pdfminer слишком полезным, но pypdf2 дал мне что-то близкое.

import PyPDF2
from StringIO import StringIO
def getPDFContent(path):
    content = ""
    p = file(path, "rb")
    pdf = PyPDF2.PdfFileReader(p)
    numPages = pdf.getNumPages()
    for i in range(numPages):
        content += pdf.getPage(i).extractText() + "\n"
    content = " ".join(content.replace(u"\xa0", " ").strip().split())
    return content

Однако это только читает файл построчно. Мне нужно решение, в котором я могу читать только часть страницы, чтобы я мог читать A, затем B, затем C и так далее. Кроме того, ответ здесь работает довольно хорошо, но порядок of
столбцов обычно искажается, и мне удалось прочитать его только построчно.


person Pistol Pete    schedule 11.04.2015    source источник


Ответы (1)


Я предполагаю, что рассматриваемые файлы PDF генерируются, а не сканируются (как в приведенном вами примере), учитывая, что вы используете pdfminer и pypdf2. Если вы знаете размер столбцов и строк в дюймах, вы можете использовать minecart (полное раскрытие: я написал minecart ). Пример кода:

import minecart

# minecart units are 1/72 inch, measured from bottom-left of the page
ROW_BORDERS = (
    72 * 1,  # Bottom row starts 1 inch from the bottom of the page
    72 * 3,  # Second row starts 3 inches from the bottom of the page
    72 * 5,  # Third row starts 5 inches from the bottom of the page
    72 * 7,  # Third row ends 7 inches from the bottom of the page
)
COLUMN_BORDERS = (
    72 * 8,  # Third col ends 8 inches from the left of the page
    72 * 6,  # Third col starts 6 inches from the left of the page
    72 * 4,  # Second col starts 4 inches from the left of the page   
    72 * 2,  # First col starts 2 inches from the left of the page
)  # reversed so that BOXES is ordered properly
BOXES = [
    (left, bot, right, top)
    for top, bot in zip(ROW_BORDERS, ROW_BORDERS[1:])
    for left, right in zip(COLUMN_BORDERS, COLUMN_BORDERS[1:])
]

def extract_output(page):
    """
    Reads the text from page and splits it into the 9 cells.

    Returns a list with 9 entries: 

        [A, B, C, D, E, F, G, H, I]

    Each item in the tuple contains a string with all of the
    text found in the cell.

    """
    res = []
    for box in BOXES:
        strings = list(page.letterings.iter_in_bbox(box))
        # We sort from top-to-bottom and then from left-to-right, based
        # on the strings' top left corner
        strings.sort(key=lambda x: (-x.bbox[3], x.bbox[0]))
        res.append(" ".join(strings).replace(u"\xa0", " ").strip())
    return res

content = []
doc = minecart.Document(open("path/to/pdf-doc.pdf", 'rb'))
for page in doc.iter_pages():
    content.append(extract_output(page))
person Felipe    schedule 05.06.2015
comment
Спасибо, я собрал решение, которое делало то, что мне было нужно, но, возможно, minecart более полезен. - person Pistol Pete; 07.06.2015
comment
Можете ли вы расширить этот ответ? Я пробовал это на pdf-файле самостоятельно, и эта справочная система не имеет смысла, насколько я могу судить. - person bjornasm; 09.05.2020