最近遇到这么一个需求:
有大概100万篇研究报告(pdf格式),想要提取出报告中的文本,图表,从而可以利用文章内容搜索报告和报告中的图表。并且还要计算报告之间的内容相似度,在用户点击一篇报告时,可以计算出与这篇报告内容相似程度较高的报告,并做相应推荐。
1、数据的提取
首先的问题是pdf中文本和图片的提取。pdf信息提取使用pdfminer包,截图使用PIL,pdfminer的介绍如下:
https://blog.csdn.net/Fighting_No1/article/details/51038942
图表提取思路:
1、遍历pdf中图片对象,利用返回的坐标截图。(注意pdfminer定义位置的y轴以最底端为0,PIL截图定义的y轴以最顶端为0)但是这样的方法有缺陷,会截出很多不必要的图,如:
需要的图可以正常截,但是缺少了图片标题,而且无法识别表格对象。,也是手动提取一系列关键字,找到最后一个关键字然后剔除关键字后面的内容。
# -*- coding: utf-8 -*-
from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed
from PIL import Image
import fitz
import re
import os
import time
class GetPic:
def __init__(self, filename, password=''):
"""
初始化
:param filename: pdf路径
:param password: 密码
"""
with open(filename, 'rb') as file:
# 创建文档分析器
self.parser = PDFParser(file)
# 创建文档
self.doc = PDFDocument()
# 连接文档与文档分析器
self.parser.set_document(self.doc)
self.doc.set_parser(self.parser)
# 初始化, 提供初始密码, 若无则为空字符串
self.doc.initialize(password)
# 检测文档是否提供txt转换, 不提供就忽略, 抛出异常
if not self.doc.is_extractable:
raise PDFTextExtractionNotAllowed
else:
# 创建PDF资源管理器, 管理共享资源
self.resource_manager = PDFResourceManager()
# 创建一个PDF设备对象
self.laparams = LAParams()
self.device = PDFPageAggregator(self.resource_manager, laparams=self.laparams)
# 创建一个PDF解释器对象
self.interpreter = PDFPageInterpreter(self.resource_manager, self.device)
# pdf的page对象列表
self.doc_pdfs = list(self.doc.get_pages())
# 打开PDF文件, 生成一个包含图片doc对象的可迭代对象
self.doc_pics = fitz.open(filename)
def to_pic(self, doc, zoom, pg, pic_path):
"""
将单页pdf转换为pic
:param doc: 图片的doc对象
:param zoom: 图片缩放比例, type int
:param pg: 对象在doc_pics中的索引
:param pic_path: 图片保存路径
:return: 图片的路径
"""
rotate = int(0)
trans = fitz.Matrix(zoom, zoom).pr