sticker0726

最近项目用到了,把PDF转为HTML,项目背景是某国企需求:把上市公司的上市公告爬下来,要公告的发行时间,公告的标题,还有公告的内容摘要,最关键的是这个内容摘要,这个内容公告是通过PDF解析的,刚开始我们把PDF解析成了TXT,使用了PDFminer3k这个模块

pdfminer3k

import importlib
import sys
import time

importlib.reload(sys)
time1 = time.time()
# print("初始时间为:",time1)

import os.path
from pdfminer.pdfparser import PDFParser,PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal, LAParams,LTTextBox,  LTTextLine,LTChar
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed



def parse(text_path):
    # 读取PDF文本
    fp = open(text_path, \'rb\')
    #创建一个PDF文本解析器
    parser = PDFParser(fp)
    # 创建一个PDF文档对象
    doc = PDFDocument()
    # 连接分析器,与文档对象
    parser.set_document(doc)
    doc.set_parser(parser)
    # 提供初始化密码,如果没有密码,就创建一个空的字符串
    doc.initialize()
    # 检测文档是否提供txt转换,不提供就忽略
    if not doc.is_extractable:
        raise PDFTextExtractionNotAllowed
    else:
        # 创建PDF,资源管理器,来共享资源
        rsrcmgr = PDFResourceManager()
        # 创建一个PDF设备对象
        laparams = LAParams()
        device = PDFPageAggregator(rsrcmgr, laparams=laparams)
        # 创建一个PDF解释其对象
        interpreter = PDFPageInterpreter(rsrcmgr, device)
        # 循环遍历列表,每次处理一个page内容
        # doc.get_pages() 获取page列表
        for page in doc.get_pages():
            interpreter.process_page(page)
            # 接受该页面的LTPage对象
            layout = device.get_result()
            # 这里layout是一个LTPage对象 里面存放着 这个page解析出的各种对象
            # 一般包括LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal 等等
            # 想要获取文本就获得对象的text属性,
            for x in layout:
                if (isinstance(x,LTTextBoxHorizontal)):
                    with open(r\'2.txt\', \'a\',encoding=\'utf-8\') as f:
                        results = x.get_text()
                        if "cid:" not in results and results:
                            print(\'>>>>>>>>>>\',results)
                            f.write(results)


if __name__ == \'__main__\':
    pdf_path = r\'xxx.pdf\'
    parse(pdf_path)

 

此方法并不对所有的PDF有效,有的PDF会出现这样的问题

该问题还没有解决

pdftotree

官方文档地址https://pypi.org/project/pdftotree/

该方法是用来把PDF转化成HTML页面的,转化HTML页面的原因是为了提取文字方便

# import pdftotree
import subprocess
import pyocr
import importlib
import sys,os
import time
from scrapy.selector import Selector
import requests

importlib.reload(sys)
time1 = time.time()



def pdf_to_html(pdf_path):
    """
    将pdf转HTML,成功与不成功的
    :param pdf_path: pdf的本地路径
    :return:如果该文件是扫描版,返回扫描版,如果转换失败返回False,如果成功返回转化成HTML的地址
    """
    try:
        pdf_file = pdf_path
        html_output = pdf_file.split(".")[0]+".html"
        html_output_path = html_output.split("/")[-1]
        cmd = \'pdftotree\' + " " + "-o" + " " + html_output + " " + pdf_file
        b = run_command(cmd.split())
        for i in b:
            i = i.decode()
            if "cannot build tree structure" in i:
                raise Exception("该文件是PDF扫描版")
            if "tabula.errors.JavaNotFoundError" in i:
                raise Exception(
                    "tabula.errors.JavaNotFoundError: `java` command is not found from this Python process. "
                    "Please ensure Java is installed and PATH is set for `java`")
            info(f"{pdf_file}已经转换成HTML")
            html_output_path = html_output_path+html_output_path
            domain_url = "/Users/gongsi/PycharmProjects/sticker/formal/AIQT_DATA/citic_report/citic_report/down_pdf/"
            file_path = os.path.join(os.path.dirname(__file__),)
            print(">>>>file",file_path)
            if os.path.exists(domain_url+html_output_path):

                return html_output_path
            return False
    except Exception as e:
        print(\'出现错误了\', e)
        if "PDF扫描版" in e:
            return "PDF扫描版"
        return False


def run_command(command):
    """
    执行cmd命令
    :param command: cmd字符串
    :return: 包含执行命令结果的一个迭代器
    """
    p = subprocess.Popen(command,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    return iter(p.stdout.readline, b\'\')

这个方法只能解决部分PDF的转换,

其中有这些不能转化

1.PDF为扫描版。

2.会出现让你安装Java的现象。

分类:

技术点:

相关文章: