Python

Python中pdfminer3k库批量处理PDF,提取指定字符

Jaydon · 12月3日 · 2019年 · · 361次已读

需求:批量提取PDF中的作者和邮箱地址,并写入Excel表格

代码如下,使用 pdfminer3k 库。

# coding:utf8
"""
pip install pdfminer3k  需要安装此依赖
"""
from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams, LTTextBoxHorizontal
import os
import re
import csv
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter


def pdfParse(path):
    """
    pdf文字提取
    :param path:文件路径
    :return: 每页结果列表
    """
    fp = open(path, 'rb')        # 以二进制读模式打开
    praser = PDFParser(fp)       # 创建一个与文档关联的解释器
    doc = PDFDocument()          # 创建一个PDF文档的对象
    praser.set_document(doc)     # 连接文档对象
    doc.set_parser(praser)       # 连接文档解释器
    doc.initialize()             # 文档初始化
    rsrcmgr = PDFResourceManager()      # 创建PDF的资源管理器
    laparams = LAParams()               # 创建参数分析器
    device = PDFPageAggregator(rsrcmgr, laparams=laparams)      # 创建聚合器
    interpreter = PDFPageInterpreter(rsrcmgr, device)           # 创建PDF页面解析器

    results = []        #创建一个结果列表

    for page in doc.get_pages():
        interpreter.process_page(page)      # 页面解析器来解析文档
        # 接受该页面的LTPage对象
        layout = device.get_result()        # 聚合器来获取页面内容
        for x in layout:
            if isinstance(x, LTTextBoxHorizontal):
                results.append(x.get_text())
    return results

def handle_result(result, name):
    email_str = ""      # 作者邮箱
    anchor_name = ""    # 作者姓名
    is_find_email = False   # 找到邮箱标志位
    is_find_anchor = False  # 找到作者标志位
    result_dict = dict()    # 创建一个字典,用来存储结果
    #print(result)
    for i in result:
        if "mail" in i and not is_find_email:
            email_str = re.findall(r"(\wmail.*?)\n", i, re.S)     # re.S是用来匹配包含换行符的字符串
            email_str = email_str[0].strip() if email_str else ""    # 如果email_str不为空,email_str[0]就是获取正则匹配的结果,然后再加上strip()函数,去除两边的空格
            is_find_email = True if email_str else is_find_email   # 如果email_str不为空,is_find_email就等于True,已经找到邮箱

        if not is_find_anchor:
            anchor_str = i[:6]     # 含有作者名的特征,就前6个字符串里面有中文逗号
            if "," not in anchor_str:
                continue
            anchor_name = anchor_str.split(",")[0].strip()   # split函数就把"hh, hl"会拆成["hh", "hl"]
            if " " in anchor_name:    # 获取到的作者还有(曹操 ab)这种额外字符,需要根据空格去掉
                anchor_name = anchor_str.split(" ")[0]
            is_find_anchor = True

        if is_find_email and is_find_anchor:    # 如果作者和邮箱都已经获取到了,就跳出循环
            break
    result_dict[name] = {"anchor_name": anchor_name, "email_str": email_str}
    return result_dict, anchor_name, email_str


def write_csv(filename, header, data):
    f = open(filename, "w", encoding="utf-8-sig", newline='')   # newline参数可以保证写入表格不会有空行
    csv_writer = csv.writer(f, dialect='excel')
    csv_writer.writerow(header)
    for i in data:
        csv_writer.writerow(i)
    f.close()


if __name__ == '__main__':
    result_list = list()   # 写入csv表格的数据
    for path in os.listdir(os.getcwd()):   # 列举当前工作文件夹的所有文件
        if path.endswith(".pdf"):    # 文件是否已pdf结尾
            data = pdfParse(path)      # 获取pdf文本内容,得到的是该文件每一页的内容列表
            result_dict, anchor_name, email_str = handle_result(data, path[:-4])       # 获取作者和邮箱
            result_list.append([path[:-4], anchor_name, email_str])
    print(result_list)
    header = ["文件名", "作者", "邮箱"]
    write_csv("pdf_email_anchor.csv", header, result_list)


提取结果:

0 条回应