Python: pdf提取文本时如何解决合并词?
Python: How to solve merged words when extracting text from pdf?
我正在努力从一组 pdf 文件中提取单词。这些文件是我从网上下载的学术论文。
数据存储在我的本地设备中,按名称排序,遵循项目文件夹内的相对路径:'./papers/data'。你可以找到我的数据 here.
我的代码在项目回购 ('./code') 的代码文件夹中执行
代码的 pdf 单词提取部分如下所示:
import PyPDF2 as pdf
from os import listdir
#Open the files:
#I) List of files:
files_in_dir = listdir('../papers/data')
#II) Open and saving files to python objects:
papers_text_list = []
for idx in range(len(files_in_dir)):
with open(f"../papers/data/{files_in_dir[idx]}", mode="rb") as paper:
my_pdf = pdf.PdfFileReader(paper)
vars()["text_%s" % idx] = ''
for i in range(my_pdf.numPages):
page_to_print = my_pdf.getPage(i)
vars()["text_%s" % idx] += page_to_print.extractText()
papers_text_list.append(vars()["text_%s" %idx])
问题是,对于某些文本,我在 python 列表中合并了单词。
text_1.split()
[ ... ,'examinedthee', 'ectsofdi',
'erentoutdoorenvironmentsinkindergartenchildren',
'™sPAlevel,',
'ages3',
'Œ5.The',
'ndingsrevealedthatchildren',
'‚sPAlevelhigherin',
'naturalgreenenvironmentsthaninthekindergarten',
'™soutdoorenvir-',
'onment,whichindicatesgreenenvironmentso',
'erbetteropportunities',
'forchildrentodoPA.', ...]
而其他列表以正确的方式导入。
text_0.split()
['Urban','Forestry', '&', 'Urban', 'Greening', '16',
'(2016)','76–83Contents', 'lists', 'available', 'at',
'ScienceDirect', 'Urban', 'Forestry', '&', 'Urban',
'Greening', ...]
此时,我认为tokenize可以解决我的问题。所以我给了 nltk
模块一个机会。
from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer(r'\w+')
doc = tokenizer,tokenize(text_1)
paper_words = [token for token in doc]
paper_words_lower = []
for token in paper_words:
try:
word = token.lower()
except TypeError:
word = token
finally:
paper_words_lower.append(word)
['contentslistsavailableat',
'sciencedirecturbanforestry',
'urbangreening',
'journalhomepage',
'www',
'elsevier',
'com',
'locate',
'ufug',
'urbangreenspacesforchildren',
'across',
'sectionalstudyofassociationswith',
'distance',
'physicalactivity',
'screentime',
'generalhealth',
'andoverweight',
'abdullahakpinar',
'adnanmenderesüniversitesi',
'ziraatfakültesi',
'peyzajmimarl',
'bölümü',
'09100ayd',
'õn',
'turkey',
...
'sgeneralhealth',
'onlychildren',
'sagewas',
'signicantlyassociatedwiththeiroverweight',
...]
我什至尝试使用 spacy
模块...但问题仍然存在。
我这里的结论是,如果能解决问题,就得在pdf提取词部分。我发现了这个 相关问题,但解决方案无法解决我的问题。
为什么会这样?我该如何解决?
PD: 列表中的一篇论文作为麻烦的例子是"AKPINAR_2017_Urban green spaces for children.pdf"
.
您可以使用以下代码导入。
import PyPDF2 as pdf
with open("AKPINAR_2017_Urban green spaces for children.pdf", mode="rb") as paper:
my_pdf = pdf.PdfFileReader(paper)
text = ''
for i in range(my_pdf.numPages):
page_to_print = my_pdf.getPage(i)
text += page_to_print.extractText()
是的,这是提取的问题。您提到的两个示例文档中的 space 是不同的:
PDF 通常不具有始终清晰的线条和单词概念。他们在文档的特定位置放置了 characters/text 个框。提取不能像例如“逐个字符”那样读取它一个 txt 文件,它从左上角到右下角解析它并使用距离来假设什么是一行,什么是一个词等。因为第一张图片中的那个似乎不仅使用 space 字符以及字符的左右边距以创建更好的文本间距,解析器很难理解它。
每个解析器都会略有不同,因此尝试一些不同的解析器可能是有意义的,也许另一个是 trained/designed 在具有相似模式的文档上并且能够正确解析它。此外,由于示例中的 PDF 确实具有所有有效的 spaces,但是随后通过一些负边距的东西将字符彼此靠近来混淆解析器,正常复制并粘贴到 txt 文件中不会有这个问题,因为它忽略了保证金的东西。
如果我们讨论的是大量数据并且您愿意花更多时间在这方面,您可以查看 Optical Character Recognition Post Correction (OCR Post Correction) 上的一些来源,这些是试图修复解析错误的文本的模型(尽管它通常更多地关注字符不能通过不同字体正确识别的问题,而不是间距问题)。
PyPDF2 自 2018 年以来未维护。
问题是因为网上有很多推荐 PyPDF2 的页面,但现在实际上没有人使用它。
我最近做了同样的事情,直到意识到 PyPDF2 已死。我最终使用了 https://github.com/jsvine/pdfplumber。它得到积极维护,简单且性能非常好
到目前为止,最简单的方法是使用现代 PDF viewer/editor,它允许剪切和粘贴并进行一些额外的调整。我大声朗读或提取大部分学术期刊都没有问题,因为它们是(除了一个)可读文本,因此可以很好地导出为纯文本。 将其中 24 个 PDF 文件(每秒 6 个,#24of25 除外)导出为可读文本总共花费了 4 秒。 使用 forfiles /m *.pdf /C "cmd /c pdftotext -simple2 @file @fname.txt"
.将结果与您的第一个不可读示例进行比较。
然而,有一个例外是 Hernadez_2005,因为要提取图像,需要对编辑进行大量(并非微不足道的)培训以处理科学术语和外来连字符以及不断变化的样式。但是可以通过写字板中的一些工作产生足够好的结果,适合在 Microsoft Word 中编辑,您可以将其保存为纯文本以便在 Python.
中解析
我正在努力从一组 pdf 文件中提取单词。这些文件是我从网上下载的学术论文。
数据存储在我的本地设备中,按名称排序,遵循项目文件夹内的相对路径:'./papers/data'。你可以找到我的数据 here.
我的代码在项目回购 ('./code') 的代码文件夹中执行
代码的 pdf 单词提取部分如下所示:
import PyPDF2 as pdf
from os import listdir
#Open the files:
#I) List of files:
files_in_dir = listdir('../papers/data')
#II) Open and saving files to python objects:
papers_text_list = []
for idx in range(len(files_in_dir)):
with open(f"../papers/data/{files_in_dir[idx]}", mode="rb") as paper:
my_pdf = pdf.PdfFileReader(paper)
vars()["text_%s" % idx] = ''
for i in range(my_pdf.numPages):
page_to_print = my_pdf.getPage(i)
vars()["text_%s" % idx] += page_to_print.extractText()
papers_text_list.append(vars()["text_%s" %idx])
问题是,对于某些文本,我在 python 列表中合并了单词。
text_1.split()
[ ... ,'examinedthee', 'ectsofdi', 'erentoutdoorenvironmentsinkindergartenchildren', '™sPAlevel,', 'ages3', 'Œ5.The', 'ndingsrevealedthatchildren', '‚sPAlevelhigherin', 'naturalgreenenvironmentsthaninthekindergarten', '™soutdoorenvir-', 'onment,whichindicatesgreenenvironmentso', 'erbetteropportunities', 'forchildrentodoPA.', ...]
而其他列表以正确的方式导入。
text_0.split()
['Urban','Forestry', '&', 'Urban', 'Greening', '16', '(2016)','76–83Contents', 'lists', 'available', 'at', 'ScienceDirect', 'Urban', 'Forestry', '&', 'Urban', 'Greening', ...]
此时,我认为tokenize可以解决我的问题。所以我给了 nltk
模块一个机会。
from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer(r'\w+')
doc = tokenizer,tokenize(text_1)
paper_words = [token for token in doc]
paper_words_lower = []
for token in paper_words:
try:
word = token.lower()
except TypeError:
word = token
finally:
paper_words_lower.append(word)
['contentslistsavailableat', 'sciencedirecturbanforestry', 'urbangreening', 'journalhomepage', 'www', 'elsevier', 'com', 'locate', 'ufug', 'urbangreenspacesforchildren', 'across', 'sectionalstudyofassociationswith', 'distance', 'physicalactivity', 'screentime', 'generalhealth', 'andoverweight', 'abdullahakpinar', 'adnanmenderesüniversitesi', 'ziraatfakültesi', 'peyzajmimarl', 'bölümü', '09100ayd', 'õn', 'turkey', ... 'sgeneralhealth', 'onlychildren', 'sagewas', 'signicantlyassociatedwiththeiroverweight', ...]
我什至尝试使用 spacy
模块...但问题仍然存在。
我这里的结论是,如果能解决问题,就得在pdf提取词部分。我发现了这个
为什么会这样?我该如何解决?
PD: 列表中的一篇论文作为麻烦的例子是"AKPINAR_2017_Urban green spaces for children.pdf"
.
您可以使用以下代码导入。
import PyPDF2 as pdf
with open("AKPINAR_2017_Urban green spaces for children.pdf", mode="rb") as paper:
my_pdf = pdf.PdfFileReader(paper)
text = ''
for i in range(my_pdf.numPages):
page_to_print = my_pdf.getPage(i)
text += page_to_print.extractText()
是的,这是提取的问题。您提到的两个示例文档中的 space 是不同的:
PDF 通常不具有始终清晰的线条和单词概念。他们在文档的特定位置放置了 characters/text 个框。提取不能像例如“逐个字符”那样读取它一个 txt 文件,它从左上角到右下角解析它并使用距离来假设什么是一行,什么是一个词等。因为第一张图片中的那个似乎不仅使用 space 字符以及字符的左右边距以创建更好的文本间距,解析器很难理解它。
每个解析器都会略有不同,因此尝试一些不同的解析器可能是有意义的,也许另一个是 trained/designed 在具有相似模式的文档上并且能够正确解析它。此外,由于示例中的 PDF 确实具有所有有效的 spaces,但是随后通过一些负边距的东西将字符彼此靠近来混淆解析器,正常复制并粘贴到 txt 文件中不会有这个问题,因为它忽略了保证金的东西。
如果我们讨论的是大量数据并且您愿意花更多时间在这方面,您可以查看 Optical Character Recognition Post Correction (OCR Post Correction) 上的一些来源,这些是试图修复解析错误的文本的模型(尽管它通常更多地关注字符不能通过不同字体正确识别的问题,而不是间距问题)。
PyPDF2 自 2018 年以来未维护。
问题是因为网上有很多推荐 PyPDF2 的页面,但现在实际上没有人使用它。
我最近做了同样的事情,直到意识到 PyPDF2 已死。我最终使用了 https://github.com/jsvine/pdfplumber。它得到积极维护,简单且性能非常好
到目前为止,最简单的方法是使用现代 PDF viewer/editor,它允许剪切和粘贴并进行一些额外的调整。我大声朗读或提取大部分学术期刊都没有问题,因为它们是(除了一个)可读文本,因此可以很好地导出为纯文本。 将其中 24 个 PDF 文件(每秒 6 个,#24of25 除外)导出为可读文本总共花费了 4 秒。 使用 forfiles /m *.pdf /C "cmd /c pdftotext -simple2 @file @fname.txt"
.将结果与您的第一个不可读示例进行比较。
然而,有一个例外是 Hernadez_2005,因为要提取图像,需要对编辑进行大量(并非微不足道的)培训以处理科学术语和外来连字符以及不断变化的样式。但是可以通过写字板中的一些工作产生足够好的结果,适合在 Microsoft Word 中编辑,您可以将其保存为纯文本以便在 Python.
中解析