4

因此,我试图从一些 PDF 中获取特定的文本,并且我正在使用 Python 和 PDFMiner,但由于 2013 年11 月发生的 API 更改而遇到了一些麻烦。基本上,要从 PDF 中获取我想要的部分文本,我目前必须将整个文件转换为文本,然后使用字符串函数来获取我想要的部分。我想要做的是循环浏览 PDF 的每一页,并将每一页一一转换为文本。然后,一旦我找到了我想要的部分,我就会阻止它阅读那个 PDF。

我将发布位于我的文本编辑器 atm 中的代码,但它不是工作版本,它更像是高效解决方案的中途版本:P

#!/usr/bin/env python
# -*- coding: utf-8 -*- 

from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.pdfdevice import PDFDevice
from pdfminer.converter import LTChar, TextConverter
from pdfminer.layout import LAParams
from subprocess import call
from cStringIO import StringIO
import re
import sys
import os

argNum = len(sys.argv)
pdfLoc = str(sys.argv[1]) #CLI arguments

def convert_pdf_to_txt(path): #converts pdf to raw text (not my function)
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    fp = file(path, 'rb')
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    password = ""
    maxpages = 0
    caching = True
    pagenos=set()
    for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
        interpreter.process_page(page)

    fp.close()
    device.close()
    str = retstr.getvalue()
    retstr.close()
    return str

if (pdfLoc[-4:] == ".pdf"):
    contents = ""
    try: # Get the outlines (contents) of the document
        fp = open(pdfLoc, 'rb') #open a pdf document for reading
        parser = PDFParser(fp)
        document = PDFDocument(parser)
        outlines = document.get_outlines()
        for (level,title,dest,a,se) in outlines:
            title = re.sub(r".*\s", "", title) #get raw titles, stripped of formatting
            contents += title + "\n"
    except: #if pdfMiner can't get contents then manually get contents from text conversion
        #contents = convert_pdf_to_txt(pdfLoc)
        #startToCpos = contents.find("TABLE OF CONTENTS")
        #endToCpos = contents.rfind(". . .")
        #contents = contents[startToCpos:endToCpos+8]

        fp = open(pdfLoc, 'rb') #open a pdf document for reading
        parser = PDFParser(fp)
        document = PDFDocument(parser)
        pages = PDFPage(document, 3, {'Resources':'thing', 'MediaBox':'Thing'}) #God knows what's going on here
        for pageNumber, page in enumerate(pages.get_pages(PDFDocument, fp)): #The hell is the first argument?
            if pageNumber == 42:
                print "Hello"

        #for line in s:
        #   print line
        #   if (re.search("(\.\s){2,}", line) and not re.search("NOTES|SCOPE", line)):
        #       line = re.sub("(\.\s){2,}", "", line)
        #       line = re.sub("(\s?)*[0-9]*\n", "\n", line)
        #       line = re.sub("^\s", "", line)
        #       print line,


        #contents = contents.lower()
        #contents = re.sub("“", "\"", contents)
        #contents = re.sub("”", "\"", contents)
        #contents = re.sub("fi", "f", contents)
        #contents = re.sub(r"(TABLE OF CONTENTS|LIST OF TABLES|SCOPE|REFERENCED DOCUMENTS|Identification|System (o|O)verview|Document (o|O)verview|Title|Page|Table|Tab)(\n)?|\.\s?|Section|[0-9]", "", contents)
        #contents = re.sub(r"This document contains proprietary information and may not be reproduced in any form whatsoever, nor may be used by or its contents divulged to third\nparties without written permission from the ownerAll rights reservedNumber:  STP SMEDate: -Jul-Issue: A  of CMC STPNHIndustriesCLASSIFICATION\nNATO UNCLASSIFIED                  AGUSTAEUROCOPTEREUROCOPTER DEUTSCHLAND                 FOKKER", "", contents)
        #contents = re.sub(r"(\r?\n){2,}", "", contents)
        #contents = contents.lstrip()
        #contents = contents.rstrip()
    #print contents
else:
    print "Not a valid PDF file"

这是这样做的旧方法(或者至少知道旧方法是如何做到的,线程对我来说不是很有用)。但是现在我必须使用 PDFPage.get_pages 而不是 PDFDocument.get_pages 并且方法及其参数完全不同。

目前,我正试图弄清楚我传递给 PDFPage 的 get_pages 方法的“Klass”变量到底是什么

如果有人能对 API 的这一部分有所了解,甚至提供一个工作示例,我将非常感激。

4

2 回答 2

1

尝试使用PyPDF2。它使用起来要简单得多,而且不像 PDFMiner 那样不必要的功能丰富(这在您的情况下很好)。这就是您想要的,而且实现起来非常简单。

from PyPDF2 import PdfFileReader

PDF = PdfFileReader(file(pdf_fp, 'rb'))

if PDF.isEncrypted:
    decrypt = PDF.decrypt('')
    if decrypt == 0:
        print "Password Protected PDF: " + pdf_fp
        raise Exception("Nope")
    elif decrypt == 1 or decrypt == 2:
        print "Successfully Decrypted PDF"

for page in PDF.pages:
    print page.extractText()
    '''page.extractText() is the unicode string of the contents of the page
    And I am assuming you know how to play with a string and use regex
    If you find what you want just break like so:
    if some_condition == True:
        break'''
于 2014-10-17T18:13:02.080 回答
0

也许我来晚了,你已经解决了这个问题,但仍然供将来参考:

经过相当多的搜索,我记得这个链接,我会从中指出以下部分(加粗的相关部分):

Python 决定以一种使方法所属的实例自动传递但不自动接收的方式来执行方法:方法的第一个参数是调用该方法的实例。这使得方法与函数完全一样,并让您自己使用实际名称(尽管 self 是惯例,当您使用其他东西时人们通常会皱眉头。) self 对于代码来说并不特殊,它只是另一个对象。

于 2014-03-04T22:30:55.127 回答