我试图使用Python提取包含在这个PDF文件中的文本。

我正在使用PyPDF2包(版本1.27.2),并有以下脚本:

import PyPDF2

with open("sample.pdf", "rb") as pdf_file:
    read_pdf = PyPDF2.PdfFileReader(pdf_file)
    number_of_pages = read_pdf.getNumPages()
    page = read_pdf.pages[0]
    page_content = page.extractText()
print(page_content)

当我运行代码时,我得到以下输出,这与PDF文档中包含的输出不同:

 ! " # $ % # $ % &% $ &' ( ) * % + , - % . / 0 1 ' * 2 3% 4
5
 ' % 1 $ # 2 6 % 3/ % 7 / ) ) / 8 % &) / 2 6 % 8 # 3" % 3" * % 31 3/ 9 # &)
%

如何提取PDF文档中的文本?


当前回答

我在寻找一个简单的解决方案来使用python 3。X和窗口。textract似乎不支持,这是不幸的,但如果你正在寻找一个简单的解决方案的windows/python 3签出tika包,真的直接阅读pdf。

Tika-Python是绑定到Apache Tika™REST服务的Python,允许在Python社区中本地调用Tika。

from tika import parser # pip install tika

raw = parser.from_file('sample.pdf')
print(raw['content'])

注意,Tika是用Java编写的,因此需要安装Java运行时

其他回答

它包括根据文档中的页数动态设置为每个PDF页创建一个新工作表。

import PyPDF2 as p2
import xlsxwriter

pdfFileName = "sample.pdf"
pdfFile = open(pdfFileName, 'rb')
pdfread = p2.PdfFileReader(pdfFile)
number_of_pages = pdfread.getNumPages()
workbook = xlsxwriter.Workbook('pdftoexcel.xlsx')

for page_number in range(number_of_pages):
    print(f'Sheet{page_number}')
    pageinfo = pdfread.getPage(page_number)
    rawInfo = pageinfo.extractText().split('\n')

    row = 0
    column = 0
    worksheet = workbook.add_worksheet(f'Sheet{page_number}')

    for line in rawInfo:
        worksheet.write(row, column, line)
        row += 1
workbook.close()

使用textract。

http://textract.readthedocs.io/en/latest/ https://github.com/deanmalmgren/textract

它支持包括pdf在内的多种文件类型

import textract
text = textract.process("path/to/file.extension")

Pdfplumber是一个更好的从pdf中读取和提取数据的库。它还提供了读取表数据的方法,在经历了大量这样的库之后,pdfplumber最适合我。

请注意,它最适合机器编写的pdf,而不是扫描的pdf。

import pdfplumber
with pdfplumber.open(r'D:\examplepdf.pdf') as pdf:
first_page = pdf.pages[0]
print(first_page.extract_text())

Camelot似乎是在Python中从pdf中提取表的一个相当强大的解决方案。

乍一看,它似乎实现了几乎和CreekGeek建议的tabura -py包一样准确的提取,CreekGeek在可靠性方面已经超过了任何其他发布的解决方案,但它应该是更可配置的。此外,它有自己的精度指示器(results.parsing_report),以及强大的调试功能。

Camelot和Tabula都将结果作为Pandas的dataframe提供,因此之后很容易调整表。

pip install camelot-py

(不要与卡梅洛特的包装混淆。)

import camelot

df_list = []
results = camelot.read_pdf("file.pdf", ...)
for table in results:
    print(table.parsing_report)
    df_list.append(results[0].df)

它还可以输出结果为CSV, JSON, HTML或Excel。

卡梅洛特的到来是以牺牲许多属地为代价的。

NB :由于我的输入非常复杂,有许多不同的表,我最终使用Camelot和Tabula,根据表,以达到最好的结果。

在尝试textract(似乎有太多依赖项)和pypdf2(无法从我测试的pdf中提取文本)和tika(太慢)后,我最终使用xpdf中的pdftotext(正如已经在另一个答案中建议的那样),并直接从python中调用二进制(您可能需要调整路径到pdftotext):

import os, subprocess
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
args = ["/usr/local/bin/pdftotext",
        '-enc',
        'UTF-8',
        "{}/my-pdf.pdf".format(SCRIPT_DIR),
        '-']
res = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = res.stdout.decode('utf-8')

有pdftotext,它基本上相同,但这假设pdftotext在/usr/local/bin中,而我在AWS lambda中使用这个,并希望从当前目录使用它。

顺便说一句:要在lambda上使用这个,你需要把二进制文件和依赖项放到libstdc++中。到函数中。我个人需要编译xpdf。由于这方面的说明会让这个答案变得更糟,我把它们放在了我的个人博客上。