【问题标题】:Extracting text from pdf using Python and Pypdf2使用 Python 和 Pypdf2 从 pdf 中提取文本
【发布时间】:2017-03-12 02:31:15
【问题描述】:

我想使用 Python 和 PYPDF 包从 pdf 文件中提取文本。 这是我的pdf fie,这是我的代码:

import PyPDF2
opened_pdf = PyPDF2.PdfFileReader('test.pdf', 'rb')

p=opened_pdf.getPage(0)

p_text= p.extractText()
# extract data line by line
P_lines=p_text.splitlines()
print P_lines

我的问题是 P_lines 无法逐行提取数据并导致一个巨大的字符串。我想逐行提取文本来分析它。关于如何改进它的任何建议? 谢谢! 这是代码返回的字符串:

[u'受 29 CFR 1910.1200(i) 约束的化学品的成分信息 和附录 D 来自供应商材料安全数据表 (MSDS)** 信息基于最大可能 浓度,因此总量可能超过 100%* 总水量 来源可能包括淡水、采出水和/或回收水 水0.01271%72.00%7732-18-5水0.00071%4.00%1310-73-2钠 氢氧化物0.00424%24.00%533-74-4Dazomat BiocidePumpcoPlexcide 24L0.00828%75.00%有机膦酸 盐类0.00276%25.00%67-56-1甲醇阻垢剂PumpcoPlexaid 6730.00807%30.00%7732-18-5水0.00188%7.00%聚乙氧基化醇表面活性剂0.00753%28.00%9003-06-9铵 盐类0.00941%35.00%64742-47-8石油馏分摩擦 减速机PumpcoPlexslick 9210.05029%60.00%7732-18-5水0.03353%40.00%7647-01-0氯化氢盐酸PumpcoHCL9.84261%100.00%14808-60-7结晶 SilicaProppantPumpcoSand90.01799%100.00%7732-18-5WaterCommentsMaximumIngredientConcentrationin HF Fluid(% by mass)**MaximumIngredientConcentrationin Additive(% by 质量)**化学文摘服务编号(CAS #)成分用途供应商商品名称水力压裂液成分:2,608,032 总水量(加仑)*:7,595 真垂直 深度(TVD):气体生产类型:NAD27Long/Lat 投影:32.558525纬度:-97.215242经度:Ole Gieser Unit D 6HWell 名称和编号:XTO EnergyOperator 名称:42-439-35084API 编号:塔兰特县:德克萨斯州:2010 年 12 月 10 日断裂日期液压 压裂液产品成分信息公开']

文件截图:

【问题讨论】:

  • 我们可以看看返回的字符串的例子吗
  • 这是它返回的内容:[u'受 29 CFR 1910.1200(i) 和附录 D 约束的化学品的成分信息来自供应商材料安全数据表 (MSDS)** 信息基于最大浓度潜力,因此总量可能超过 100%* 总水量来源可能包括淡水、采出水和/或循环水0.01271%72.00%7732-18-5Water0.00071%4.00%1310-73- 2氢氧化钠0.00424%24.00%533-74-4DazomatBiocidePumpcoPlexcide 24L0.00828%....
  • 将该字符串添加到评论中不太清楚的问题中,您还可以指出字符串中您希望换行符出现的位置
  • 刚刚添加到问题中
  • 你能粘贴原始PDF吗?或者至少是第一页?

标签: python pdf text pypdf


【解决方案1】:
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from io import StringIO

def convert_pdf_to_txt(path):
    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)

    text = retstr.getvalue()

    fp.close()
    device.close()
    retstr.close()
    return text
print(convert_pdf_to_txt('test.pdf').strip().split('\n\n'))

输出

水力压裂液产品成分信息公开

断裂日期状态:县:API 编号:操作员名称:井名和 编号:经度:纬度:经度/纬度投影:生产类型: 真实垂直深度 (TVD):总水量 (gal)*:

12/10/2010 Texas Tarrant 42-439-35084 XTO Energy Ole Gieser Unit D 6H -97.215242 32.558525 NAD27 气体 7,595 2,608,032

水力压裂液成分:

商品名

供应商

目的

成分

化学文摘服务号

(CAS #)

最大成分

专注

添加剂(按质量)**

评论

最大成分

专注

在 HF 流体中(按质量计)**

水砂盐酸盐

普普科普科普科

盐酸支撑剂

Plexslick 921

水泵

减摩剂

Plexaid 673

水泵

阻垢剂

Plexcide 24L

水泵

杀菌剂

结晶二氧化硅

氯化氢水

石油馏分铵盐聚乙氧基化醇 表面活性剂 水

甲醇有机膦酸盐

达佐马特氢氧化钠水

7732-18-5 14808-60-7

7647-01-0 7732-18-5

64742-47-8 9003-06-9

7732-18-5

67-56-1

533-74-4 1310-73-2 7732-18-5

100.00 100.00

90.01799 9.84261

40.00 60.00

35.00 28.00 7.00 30.00

25.00 75.00

24.00 4.00 72.00

0.03353 0.05029

0.00941 0.00753 0.00188 0.00807

0.00276 0.00828

0.00424 0.00071 0.01271

  • 总水量来源可能包括淡水、采出水和/或循环水 ** 信息基于最大的集中潜力,因此总数可能超过 100

受 29 CFR 1910.1200(i) 约束的化学品的成分信息 和附录 D 来自供应商材料安全数据表 (MSDS)

【讨论】:

  • 我在运行您的代码时得到以下代码:UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0: ordinal not in range(128)
  • 你的 Python 版本是多少?我正在使用 2.7。
  • Python 2.7.12 Windows 10
  • 不,我没能做到,不幸的是我得到了上面列出的相同错误。但是,即使我的代码有效,它也不会有用,因为它不是逐行解析的。感谢您的努力
【解决方案2】:

textract 在 python3 中工作正常,使用 tesseract 方法。示例代码:

import textract
text = textract.process("pdfs/testpdf1.pdf", method='tesseract')
print(text)
with open('textract-results.txt', 'w+') as f:
    f.write(str(text))

https://pypi.org/project/textract/

【讨论】:

  • 我认为 textract 在这里不是正确的答案。它更像是一个企业解决方案。没有信用卡您无法访问它。通常,这里的人们正在寻找开源解决方案或一些基于编码的解决方案,而这更像是一个付费的黑盒解决方案。所以我认为如果在解决方案之前有一个免责声明会更好,比如“这可能不是每个人的正确解决方案,因为它更像是 aws 提供的企业解决方案”。这个答案浪费了我的时间,而不是节省了时间。所以被否决了。
  • @penduDev 请查看我对答案的更新。在我回答时,亚马逊没有一个名为 Textract 的东西,不幸的是它与 pypi 中的开源库同名。请下载并使用这个:pypi.org/project/textract,因为它确实很容易开箱即用。并且请删除反对票,因为您对 AWS / 企业解决方案的假设是错误的。我非常寻求和使用开源解决方案,并在这里和任何我可以分享的地方分享它们。
  • 哦..我误会了!感谢@jamescampbell 的澄清 ..我的问题以另一种方式解决了,但希望其他人觉得这有帮助。谢谢你! :)
【解决方案3】:

确保您要导入的 PDF 中确实包含换行符。如果没有,那么p_text.splitlines() 将无处可拆分字符串!如果有特定字符,可以使用p_text.split("the linebreak character")

编辑:根据您的 PDF,我不确定是否有办法将其按行拆分,因为它似乎是静态格式而不是线性格式。 (文本在 PDF 中按位置放置,而不是逐行放置)。

【讨论】:

  • 是的 splitlines() 不起作用。有没有其他的pdf提取包可以做到这一点?
  • @Amir 看到我的回答。
【解决方案4】:

这是我提出的完全基于@SmartManoj 答案的函数,但通过使用with 语句已更新为更简洁(在我看来),消除了不必要的变量(即关键字参数 self解释)以及产生页面的文本。

from typing import Generator  
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from io import StringIO

def pages_as_txt(path) -> Generator[str, None, None]:
    rsrcmgr = PDFResourceManager()
    with StringIO() as retstr, TextConverter(rsrcmgr, retstr, codec='utf-8', laparams=LAParams()) as device:
        interpreter = PDFPageInterpreter(rsrcmgr, device)

        with open(path, 'rb') as fp:
            for page in PDFPage.get_pages(fp, check_extractable=False):
                interpreter.process_page(page)
                yield retstr.getvalue()
                retstr.truncate(0)
                retstr.seek(0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 2022-10-05
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    相关资源
    最近更新 更多