我正在使用python2.7和PDFminer从pdf中提取文本。我注意到有时PDFminer会给我带有奇怪字母的单词,但pdf观众不会。另外对于一些pdf文档,PDFminer和其他pdf查看器返回的结果是相同的(奇怪的),但是有文档,pdf查看器可以识别文本(复制粘贴)。以下是返回值的示例:
来自pdf viewer:فتحبابا ستيرادالبي ضوالدجاجالمجمد
来自PDFMiner:óªéªdG êÉ````LódGh ¢†``«ÑdG OGô``«à°SG ÜÉ
Hí``àa
所以我的问题是我可以得到与pdf viewer相同的结果,以及PDFminer有什么问题。它是否缺少我不知道的编码。
答案 0 :(得分:1)
是
当使用自定义字体编码时会发生这种情况,例如identity-H,identity-V等,但字体未正确嵌入。
pdfminer在这种情况下提供垃圾输出,因为需要编码来解释文本
答案 1 :(得分:0)
您尝试阅读的PDF文件可能还有pdfMiner尚不支持的编码。
上个月我遇到了类似的问题,最后通过使用名为" pdfBox"的Java库解决了这个问题。并从python中调用它。 pdfBox库支持我需要的编码,并且像魅力一样工作!。
首先我从official site下载了pdfbox 然后从我的代码中引用.jar文件的路径。
这是我使用的代码的简化版本(未经测试,但基于我原来的测试代码)。
您将需要subprocess32,您可以通过调用pip install subprocess32
import subprocess32 as subprocess
import os
import tempfile
def extractPdf(file_path, pdfboxPath, timeout=30, encoding='UTF-8'):
#tempfile = temp_file(data, suffix='.pdf')
try:
command_args = ['java', '-jar', os.path.expanduser(pdfboxPath), 'ExtractText', '-console', '-encoding', encoding, file_path]
status, stdout, stderr = external_process(command_args, timeout=timeout)
except subprocess.TimeoutExpired:
raise RunnableError('PDFBox timed out while processing document')
finally:
pass#os.remove(tempfile)
if status != 0:
raise RunnableError('PDFBox returned error status code {0}.\nPossible error:\n{1}'.format(status, stderr))
# We can use result from PDFBox directly, no manipulation needed
pdf_plain_text = stdout
return pdf_plain_text
def external_process(process_args, input_data='', timeout=None):
process = subprocess.Popen(process_args,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
try:
(stdout, stderr) = process.communicate(input_data, timeout)
except subprocess.TimeoutExpired as e:
# cleanup process
# see https://docs.python.org/3.3/library/subprocess.html?highlight=subprocess#subprocess.Popen.communicate
process.kill()
process.communicate()
raise e
exit_status = process.returncode
return (exit_status, stdout, stderr)
def temp_file(data, suffix=''):
handle, file_path = tempfile.mkstemp(suffix=suffix)
f = os.fdopen(handle, 'w')
f.write(data)
f.close()
return file_path
if __name__ == '__main__':
text = extractPdf(filename, 'pdfbox-app-2.0.3.jar')
` 这段代码并非完全由我编写。我按照其他堆栈溢出答案的建议,但它是一个月前,所以我失去了原始的来源。如果有人找到我收到此代码段的原始帖子,请告诉我,这样我就可以为他们提供他们应得的代码。