解决pdfminer ImportError: cannot import name process_pdf

2023-05-16

Python 2.7
IDE Pycharm 5.0.3
pdfminer 20140328


解决问题和测试多个版本读pdf

解决问题

在进行PDF读取的时候,遇到pdfminer ImportError: cannot import name process_pdf问题,各处搜索之后,除了stackoverflow的how to use pdfminer有比较好的总结之外,还是得看官方手册啊,这句话process_pdf function is implemented as a class method PDFPage.get_pages.所以是API 改变了点咯,妈蛋!

很少有中文文章写了,这里我把遇到的问题和解决的方法写一下,如果能解决你的问题,倍感荣幸,自己也顺便练习。


解决方法

就是:不使用process_pdf
因为pdfminer 20140328这个版本是最近的,而且不支持process_pdf,如果你想要它支持process_pdf,你可以安装pdfminer-20110515版本的,这个可以正常导入包,但是其他函数使用体验不好。我查找了几个不使用process_pdf照样能够读取PDF的几个函数,自己修改了一下,如果想直接看例子使用,请直接跳转到pdfminer使用一二则。

安装20110515版本的pdfminer请在cmd下运行该命令,当然前提你装了pip,也可以自己去github找pdfminer历史版本

pip install http://pypi.python.org/packages/source/p/pdfminer/pdfminer-20110515.tar.gz 

pdfminer安装

更加详细的参考官方手册pdfminer下载
懒得看官方,来,看我的
1.下载压缩包,解压
2.cmd命令,切换到解压后路径(使用cd 路径)
3.直接复制下面的,到你的cmd窗口,然后他会安装,这是对中文字符识别需要额外加的。官方的话是On Windows machines which don't have make command, paste the following commands on a command line prompt:

mkdir pdfminer\cmap
python tools\conv_cmap.py -c B5=cp950 -c UniCNS-UTF8=utf-8 pdfminer\cmap Adobe-CNS1 cmaprsrc\cid2code_Adobe_CNS1.txt
python tools\conv_cmap.py -c GBK-EUC=cp936 -c UniGB-UTF8=utf-8 pdfminer\cmap Adobe-GB1 cmaprsrc\cid2code_Adobe_GB1.txt
python tools\conv_cmap.py -c RKSJ=cp932 -c EUC=euc-jp -c UniJIS-UTF8=utf-8 pdfminer\cmap Adobe-Japan1 cmaprsrc\cid2code_Adobe_Japan1.txt
python tools\conv_cmap.py -c KSC-EUC=euc-kr -c KSC-Johab=johab -c KSCms-UHC=cp949 -c UniKS-UTF8=utf-8 pdfminer\cmap Adobe-Korea1 cmaprsrc\cid2code_Adobe_Korea1.txt
python setup.py install

然后你就应该装好了,试试我最后的两段代码,直接可用的。


pdfminer使用一二则

1.对本地保存的pdf文件进行读取和写入到txt
写法一:

# -*- coding: utf-8 -*-
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfpage import PDFTextExtractionNotAllowed
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.pdfdevice import PDFDevice
from pdfminer.layout import *
from pdfminer.converter import PDFPageAggregator



def Pdf2Txt(Path,Save_name):
    #来创建一个pdf文档分析器
    parser = PDFParser(Path)
    #创建一个PDF文档对象存储文档结构
    document = PDFDocument(parser)
    # 检查文件是否允许文本提取
    if not document.is_extractable:
        raise PDFTextExtractionNotAllowed
    else:
        # 创建一个PDF资源管理器对象来存储共赏资源
        rsrcmgr=PDFResourceManager()
        # 设定参数进行分析
        laparams=LAParams()
        # 创建一个PDF设备对象
        # device=PDFDevice(rsrcmgr)
        device=PDFPageAggregator(rsrcmgr,laparams=laparams)
        # 创建一个PDF解释器对象
        interpreter=PDFPageInterpreter(rsrcmgr,device)
        # 处理每一页
        for page in PDFPage.create_pages(document):
            interpreter.process_page(page)
            # 接受该页面的LTPage对象
            layout=device.get_result()
            for x in layout:
                if(isinstance(x,LTTextBoxHorizontal)):
                    with open('%s'%(Save_name),'a') as f:
                        f.write(x.get_text().encode('utf-8')+'\n')

Path = open('test1_chinese.pdf', 'rb')
Pdf2Txt(Path,'b.txt')

我直接把函数封装起来了,以后直接调用就可以了,传递的参数Path是本地pdf路径,Save_name是将要识别的文字保存在txt中的名字,默认路径为项目py文件路径。识别中文的效果像是这样的
这里写图片描述

我知道很难看,没办法,这是一篇期刊,里面各种图,影响识别的。


写法二

# -*- coding: utf-8 -*-
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from cStringIO import StringIO

def convert_pdf_to_txt(path,save_name):
    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()
    try:
        with open("%s"%save_name,"w") as f:#格式化字符串还能这么用!
            for i in str:
                f.write(i)
        print "%s Writing Succeed!"%save_name
    except:
        print "Writing Failed!"


convert_pdf_to_txt('C:\\pdfminer-master\\chapter1.pdf',"c.txt")

和写法一差不太多啦,就是个别语句不一样,这次我识别的是英文的pdf,效果如下,当然你要是识别上述的中文,那是一样样的烂!

这里写图片描述

我这是已经封装了函数了,大家要是不喜欢其中的写入txt,可以直接返回str完事,调用之后再写进去也可以的,我这人懒,就直接这么写了。


2.对pdf网页进行读取和写入到txt
这里我使用StringIO来处理,我就是不想下载到本地,就想直接读到内存里,处理下完事,这是我从CSV处理方法上借鉴过来的,改了上述代码中其中几句话,即可实现。
首先看一下在线pdf啥样的,这里用了教材上的一个pdf网页
这里写图片描述

OK,Let’s do this!
写法一:

# -*- coding: utf-8 -*-
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from cStringIO import StringIO

import urllib2


def Pdf_Write2txt(html,save_name):

    rsrcmgr = PDFResourceManager()
    # 创建一个PDF资源管理器对象来存储共赏资源
    retstr = StringIO()
    laparams=LAParams()
    device = TextConverter(rsrcmgr, retstr, codec='utf-8', laparams=laparams)
    # 创建一个PDF解释器对象

    #修改此行
    fp = StringIO(html)

    interpreter = PDFPageInterpreter(rsrcmgr, device)
    pagenos=set()
    for page in PDFPage.get_pages(fp, pagenos, maxpages=0, password="",caching=True, check_extractable=True):
        interpreter.process_page(page)
    fp.close()
    device.close()
    str = retstr.getvalue()
    retstr.close()
    try:
        with open("%s.txt"%save_name,"w") as f:#格式化字符串还能这么用!
            for i in str:
                f.write(i)
        print "%s.txt Writing Succeed!"%save_name
    except:
        print "Writing Failed!"
url="http://pythonscraping.com/pages/warandpeace/chapter1.pdf"
html = urllib2.urlopen(urllib2.Request(url)).read()
Pdf_Write2txt(html,"c1")

实现的效果,写入了c1.txt中成功

这里写图片描述


写法二

# -*- coding: utf-8 -*-
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfpage import PDFTextExtractionNotAllowed
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.pdfdevice import PDFDevice
from pdfminer.layout import *
from pdfminer.converter import PDFPageAggregator
import urllib2
from cStringIO import StringIO

def Pdf2Txt(DataIO,Save_path):
    #来创建一个pdf文档分析器
    parser = PDFParser(DataIO)
    #创建一个PDF文档对象存储文档结构
    document = PDFDocument(parser)
    # 检查文件是否允许文本提取
    if not document.is_extractable:
        raise PDFTextExtractionNotAllowed
    else:
        # 创建一个PDF资源管理器对象来存储共赏资源
        rsrcmgr=PDFResourceManager()
        # 设定参数进行分析
        laparams=LAParams()
        # 创建一个PDF设备对象
        # device=PDFDevice(rsrcmgr)
        device=PDFPageAggregator(rsrcmgr,laparams=laparams)
        # 创建一个PDF解释器对象
        interpreter=PDFPageInterpreter(rsrcmgr,device)
        # 处理每一页
        for page in PDFPage.create_pages(document):
            interpreter.process_page(page)
            # 接受该页面的LTPage对象
            layout=device.get_result()
            for x in layout:
                try:
                    if(isinstance(x,LTTextBoxHorizontal)):
                        with open('%s'%(Save_path),'a') as f:
                            #参数a,表示不会覆盖,直接追加写,和w不一样
                            f.write(x.get_text().encode('utf-8')+'\n')
                except:
                    print "Failed!"


url = "http://pythonscraping.com/pages/warandpeace/chapter1.pdf"
html = urllib2.urlopen(urllib2.Request(url)).read()
DataIO = StringIO(html)
Pdf2Txt(DataIO,'b2.txt')

结果和上述的是一样的,所以不贴图了。。。。
上述两种写法,都是实际测试并通过的,针对的是现在最新版本的pdfminer 20140328,环境是python2.7 我对本测试负责。


最后

个人推崇写法二,原作者我找不到了,这里致歉,代码我经过一些修改,更加符合使用习惯。还有就是,多看官方手册。


致谢

@Stack overflow–How do I use pdfminer as a library
@euske–pdfminer Github下载
@圆滚滚姑娘–从PDF中提取信息—-PDFMiner

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

解决pdfminer ImportError: cannot import name process_pdf 的相关文章

随机推荐