Python读取pdf页面的一部分

标签 python pdf pypdf pdfminer

我正在尝试阅读一个 pdf 文件,其中每个页面都分为 3x3 表单信息 block

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

每个条目都分为多行。一个条目的简化示例是 this card 。但其他 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,依此类推。另外,答案here效果相当好,但是
的顺序 列经常会被扭曲,我只能让它逐行读取。

最佳答案

鉴于您使用的是 pdfminerpypdf2,我假设相关 PDF 文件是生成的 PDF,而不是扫描的 PDF(如您给出的示例中所示)。如果您知道列和行的大小(以英寸为单位),则可以使用 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))

关于Python读取pdf页面的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29582564/

相关文章:

python - 类型错误 : 'in <string>' requires string as left operand not list

python - 为什么 cx_oracle execute() 现在不喜欢我的字符串?

python快速编写变量名称和值

javascript - 将 Markdown 文件转换为 PDF,同时剥离 Jekyll Front-Matter

php - Zend 框架 PDF 下划线字体

wpf - 如何将flowDocument的内容保存在PDF和Word中?

python - 使用 PyPDF2 去除 PDF 上的水印

python - 从大型(密码)列表中聚合和删除重复项的有效方法

python - 文本摘要 : failed with exit code 127//windows 10//pdftotext

python - 如何使用 PyPdf 将 Pdf 转换为 Unicode (utf-8) 格式的文本