使用Python搜索PDF中的文本?

Ins*_*rov 26 python pdf parsing text

问题
我试图通过搜索文本来确定文档的类型(例如恳求,通信,传票等),最好使用python.所有的PDF都是可搜索的,但是我还没有找到解决方案,用python解析它并应用脚本来搜索它(首先不是将它转换为文本文件,但对于n个文档来说这可能是资源密集型的).

到目前为止
做了什么我已经研究过 pypdf,pdfminer,adobe pdf文档,以及我能找到的任何问题(虽然似乎没有一个直接解决这个问题).PDFminer似乎最具潜力,但在阅读完文档之后我甚至不确定从哪里开始.

是否有一种简单有效的方法可以通过页面,行或整个文档来阅读PDF文本?或任何其他解决方法?

Pau*_*ine 34

这称为PDF挖掘,非常困难,因为:

  • PDF是一种文档格式,旨在打印,不需要解析.在PDF文档中,文本没有特定的顺序(除非顺序对于打印很重要),大多数情况下原始文本结构丢失(字母可能不会被分组为单词而单词可能不会被分组在句子中,顺序它们放在纸上往往是随机的).
  • 有大量的软件生成PDF,许多是有缺陷的.

像PDFminer这样的工具使用启发式方法根据它们在页面中的位置再次对字母和单词进行分组.我同意,界面水平相当低,但是当你知道他们试图解决什么问题时更有意义(最重要的是,选择与邻居有多接近,字母/字/行必须按顺序排列被视为段落的一部分).

一个昂贵的替代方案(在时间/计算机能力方面)为每个页面生成图像并将它们提供给OCR,如果你有一个非常好的OCR,可能值得一试.

所以我的答案是否定的,没有一种简单有效的方法可以从PDF文件中提取文本 - 如果你的文档有一个已知的结构,你可以微调规则并获得好的结果,但它始终是一个赌博.

我真的想被证明是错的.

[更新]

答案没有改变,但最近我参与了两个项目:其中一个项目是使用计算机视觉来从扫描的医院表格中提取数据.另一个从法庭记录中提取数据.我学到的是:

  1. 计算机视觉在2018年达到了凡人.如果您拥有已经分类的文档的良好样本,您可以使用OpenCV或SciKit-Image来提取功能并训练机器学习分类器以确定文档的类型.

  2. 如果您正在分析的PDF是"可搜索的",您可以使用pdftotext和贝叶斯过滤器(用于对SPAM进行分类的相同类型的算法)等软件远程提取所有文本.

因此,没有可靠有效的方法从PDF文件中提取文本,但您可能不需要一个方法来解决手头的问题(文档类型分类).


Emm*_*mma 16

我完全是个绿色手,但是这个脚本对我有用:

# import packages
import PyPDF2
import re

# open the pdf file
object = PyPDF2.PdfFileReader("test.pdf")

# get number of pages
NumPages = object.getNumPages()

# define keyterms
String = "Social"

# extract text and do the search
for i in range(0, NumPages):
    PageObj = object.getPage(i)
    print("this is page " + str(i)) 
    Text = PageObj.extractText() 
    # print(Text)
    ResSearch = re.search(String, Text)
    print(ResSearch)
Run Code Online (Sandbox Code Playgroud)

  • @AmeyPNaik 那将是修改 PDF,而不仅仅是阅读/搜索 PDF。以编程方式修改现有 PDF 而无需出现布局和格式问题则更加复杂。 (6认同)
  • 嗨,艾米,只需将“社交”更改为您要搜索的任何文本即可! (2认同)

Mik*_*ter 12

我为我所工作的公司编写了大量系统,将PDF转换成数据进行处理(发票,结算,扫描票证等),而@Paulo Scardine是正确的 - 没有完全可靠和简单的方法来做到这一点.也就是说,最快,最可靠,最不密集的方法是使用xpdf工具集的pdftotext一部分.该工具可以快速将可搜索的PDF转换为文本文件,您可以使用Python读取和解析该文件.提示:使用参数.顺便说一句,并非所有PDF都是可搜索的,只有那些包含文本的PDF.某些PDF仅包含完全没有文本的图像.-layout

  • 如果有办法将 PDF 转换为文本文件,有没有办法在不编写实际的新文件的情况下做到这一点?类似于将文档读入内存?(至少,以一种与转换它一样直接的方式?)。 (2认同)
  • @Insarov 从 pdftotext 文档中,“如果文本文件是'-',则文本将发送到标准输出。” 因此,您可以使用“grep”或类似命令将其传送到搜索。 (2认同)

Jas*_*air 6

我最近开始使用ScraperWiki来执行您描述的操作。

这是使用ScraperWiki提取PDF数据的示例

scraperwiki.pdftoxml()函数返回一个XML结构。

然后,您可以使用BeautifulSoup将其解析为可导航树。

这是我的代码-

import scraperwiki, urllib2
from bs4 import BeautifulSoup

def send_Request(url):
#Get content, regardless of whether an HTML, XML or PDF file
    pageContent = urllib2.urlopen(url)
    return pageContent

def process_PDF(fileLocation):
#Use this to get PDF, covert to XML
    pdfToProcess = send_Request(fileLocation)
    pdfToObject = scraperwiki.pdftoxml(pdfToProcess.read())
    return pdfToObject

def parse_HTML_tree(contentToParse):
#returns a navigatibale tree, which you can iterate through
    soup = BeautifulSoup(contentToParse)
    return soup

pdf = process_PDF('http://greenteapress.com/thinkstats/thinkstats.pdf')
pdfToSoup = parse_HTML_tree(pdf)
soupToArray = pdfToSoup.findAll('text')
for line in soupToArray:
    print line
Run Code Online (Sandbox Code Playgroud)

此代码将打印一大堆丑陋的<text>标签。每页都以分隔</page>,如果可以的话。

如果您希望<text>标签内的内容<b>(例如可能包含换行的标题),请使用line.contents

如果只希望每一行文本,但不包括标签,请使用 line.getText()

这很麻烦,而且很麻烦,但这将适用于可搜索的PDF文档。到目前为止,我发现这是正确的,但很痛苦。

  • 我尝试使用 scraperwiki,但出现系统找不到指定路径的错误。@JasTonAchair 任何帮助表示赞赏。 (2认同)

小智 6

这是我发现它对这个问题很满意的解决方案。在 text 变量中,您可以从 PDF 中获取文本以便在其中进行搜索。但我也保留了在本网站上找到的在关键字中吐出文本的想法:https : //medium.com/@rqaiserr/how-to-convert-pdfs-into-searchable-key-words-with-python -85aab86c544f来自我采用了这个解决方案,虽然制作 nltk 不是很简单,但它可能对进一步的目的有用:

import PyPDF2 
import textract

from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords

def searchInPDF(filename, key):
    occurrences = 0
    pdfFileObj = open(filename,'rb')
    pdfReader = PyPDF2.PdfFileReader(pdfFileObj)
    num_pages = pdfReader.numPages
    count = 0
    text = ""
    while count < num_pages:
        pageObj = pdfReader.getPage(count)
        count +=1
        text += pageObj.extractText()
    if text != "":
       text = text
    else:
       text = textract.process(filename, method='tesseract', language='eng')
    tokens = word_tokenize(text)
    punctuation = ['(',')',';',':','[',']',',']
    stop_words = stopwords.words('english')
    keywords = [word for word in tokens if not word in stop_words and  not word in punctuation]
    for k in keywords:
        if key == k: occurrences+=1
    return occurrences 

pdf_filename = '/home/florin/Downloads/python.pdf'
search_for = 'string'
print searchInPDF (pdf_filename,search_for)
Run Code Online (Sandbox Code Playgroud)


qww*_*wwq 5

我同意@Paulo PDF 数据挖掘是一个巨大的痛苦。但是您可能会成功pdftotext使用此处免费提供的 Xpdf 套件的一部分:

http://www.foolabs.com/xpdf/download.html

如果您只是在寻找单个关键字,这应该足以满足您的目的。

pdftotext是一个命令行实用程序,但使用起来非常简单。它将为您提供文本文件,您可能会发现这些文件更易于使用。