python-3.x - pdfminer:根据字体大小仅提取文本
问题描述
我只想从我的 pdf 文件中提取具有字体大小9.800000000000068
的文本。10.000000000000057
下面的代码返回一个 pdf 文件中每个文本块的字体大小及其字符的列表。
Extract_Data=[]
for page_layout in extract_pages(path):
print(page_layout)
for element in page_layout:
if isinstance(element, LTTextContainer):
for text_line in element:
for character in text_line:
if isinstance(character, LTChar):
Font_size=character.size
Extract_Data.append([Font_size,(element.get_text())])
给我一个Extract_Data
包含各种字体大小的列表
[[9.800000000000068, 'aaa\n'], [11.0, 'dffg\n'], [10.000000000000057, 'bbb\n'], [10.0, 'hs\n'], [8.0, '2\n']]
示例:字体大小10.000000000000057
Extract_Data=[]
for page_layout in extract_pages(path):
print(page_layout)
for element in page_layout:
if isinstance(element, LTTextContainer):
for text_line in element:
for character in text_line:
if isinstance(character, LTChar):
if character.size == '10.000000000000057':
element.get_text()
Extract_Data.append(element.get_text())
Data = ''.join(map(str, Extract_Data))
给我一个Data
包含所有文本的列表。我怎样才能让它只提取字体大小的'10.000000000000057'
字符?
['aaa\ndffg\nbbb\nhs\n2\n']
我还想集成到一个函数中,该函数对多个文件执行此操作,从而生成一个 pandas df,每个 pdf 都有一行。期望的输出:[['aaa\n bbb\n']]
. 按照 eksewhere 的建议将像素转换为点 ( int(character.size) * 72 / 96
) 并没有帮助。也许这与此有关?https://github.com/pdfminer/pdfminer.six/issues/202
这是稍后将集成的功能:
directory = 'C:/Users/Sample/'
resource_manager = PDFResourceManager()
for file in os.listdir(directory):
if not file.endswith(".pdf"):
continue
fake_file_handle = io.StringIO()
manager = PDFResourceManager()
device = PDFPageAggregator(manager, laparams=params)
interpreter = PDFPageInterpreter(manager, device)
device = TextConverter(interpreter, fake_file_handle, laparams=LAParams())
params = LAParams(detect_vertical=True, all_texts=True)
elements = []
with open(os.path.join(directory, file), 'rb') as fh:
parser = PDFParser(fh)
document = PDFDocument(parser, '')
if not document.is_extractable:
raise PDFTextExtractionNotAllowed
for page in enumerate (PDFPage.create_pages(document)):
for element in page:
解决方案
Pdfminer 是错误的工具。
使用 pdfplumber 代替https://github.com/jsvine/pdfplumber,因为它具有过滤对象的实用功能(例如,根据您尝试执行的字体大小),而 pdfminer 主要用于获取所有文本。
import pdfplumber
def get_filtered_text(file_to_parse: str) -> str:
with pdfplumber.open(file_to_parse) as pdf:
text = pdf.pages[0]
clean_text = text.filter(lambda obj: not (obj["object_type"] == "char" and obj["size"] != 9))
print(clean_text.extract_text())
get_filtered_text("./my_pdf.pdf")
我上面展示的例子比你的更容易,因为它只检查字体大小 9.0,你有
9.800000000000068 和 10.000000000000057
所以 obj["size"] 条件在你的情况下会更复杂
obj["size"]
有数据类型Decimal
( from decimal import Decimal
) 所以你可能不得不做类似的事情obj["size"].compare(Decimal(9.80000000068)) == 0
推荐阅读
- xamarin.forms - 如果不在 UI 线程上,我是否需要等待 Xamarin Forms Clipboard.SetTextAsync()?
- git - 简单的 git rebase 间歇性地需要 --continue 未知原因 -- 可能是什么原因造成的?
- php - 是否可以使用 memcache 而不是 memcached 和 Symfony 来存储会话?
- javascript - 在 React componentDidUpdate 中添加和组合数据
- project-reactor - 如何在同一个通量上执行两个操作
- angular - Angular 最佳实践在哪里放置更改状态的字符串
- java - 你能在那个类中有一个类的实例吗?
- google-docs - Integromat - 将 Google Doc 保存到 Airtable 附件字段
- javascript - React-Router:以编程方式从根元素路由到路由
- c# - 如何为某些端点编写自定义预检查中间件?