用Python读取Word文件并提取标题

news/2024/7/8 3:39:02 标签: word, python3.9, docx, OrderedDict

前言

在日常工作中,我们经常需要处理Word文档,特别是从中提取关键信息,如标题、段落等。今天,我们将利用Python来实现这一功能,并为大家提供一段完整的代码示例。

准备工作

首先,你需要安装python-docx库,这是一个用于处理Word文档的Python库和collections库,用于数据去重

。你可以使用以下命令安装它:

pip install python-docx collections

代码讲解

下面是实现该功能的完整代码:

#!/usr/bin/env python3
# coding:utf-8
import re
import docx
import os
from collections import OrderedDict


interfere = []
garde = []

'''判断依据'''
first_title = []
first_title1 = []
first_title2 = []

kew_word = ['是', '要']
one_characters = ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬', '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳', '第', '甲', '乙', '丙', '—', 'Ⅰ', 'Ⅱ', 'Ⅲ', 'Ⅳ', 'Ⅴ', 'Ⅵ', 'Ⅶ', 'Ⅷ', 'Ⅸ', 'Ⅹ']
two_characters = []
three_characters = []
four_characters = []
five_characters = []
year = []
number1 = []
number2 = []
spell = []
spell1 = ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬', '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳', 'Ⅰ', 'Ⅱ', 'Ⅲ', 'Ⅳ', 'Ⅴ', 'Ⅵ', 'Ⅶ', 'Ⅷ', 'Ⅸ', 'Ⅹ']


def main():
    creat_role()
    path = r'./test'  #  测试文件夹
    file_name = os.listdir(path)
    for i in file_name:
        file_path = path + '\\' + i
        content = read_data(file_path)
        # print(content)
        title = get_title(content)
        get_second_title(title)

    garde_unique = list(OrderedDict.fromkeys(garde))
    for i in garde_unique:
        print(i)


def read_data(filename):
    content = []
    doc = docx.Document(filename)
    for para in doc.paragraphs:
        for r in para.runs:
            if r.bold and 5 < len(r.text) < 50 and r.text[-1] != ',':
                content.append(r.text + 'label')
            else:
                content.append(para.text)
    return content


def get_title(ls):
    title = []
    for i in ls:
        i = re.sub('\s', '', i)
        if len(i) == 0:
            continue
        else:
            if i[:1] in one_characters or i[:2] in two_characters or i[:3] in three_characters or i[:4] in four_characters or i[:5] in five_characters or i[:-5] == 'label':
                title.append(i)
    return title


def get_second_title(ls):
    label = ['<first>', '<second>', '<third>', '<fourth>', '<fifth>']
    mark = []
    number = []
    for i in ls:
        if i[1] == '年' and i[3] != ',':
             continue
        elif str(i[:4]) in year:
            continue
        elif i[:2] == '一九' or i[:2] == '二零':
            continue
        elif i[:2] in first_title or i[:3] in first_title1 or i[:4] in first_title2:
            if '。' in i:
                garde.append(i.split('。')[0] + label[0])
            else:
                garde.append(i + label[0])
            mark = []
        else:
            if i[0] in interfere:
                mark.append('一')
            elif i[:1].isdecimal() == True:
                mark.append('壹')
            elif i[:2].isdecimal() == True:
                mark.append('壹')
            elif i[:1] in spell:
                mark.append('A')
            elif i[:1] in spell1:
                mark.append('①')
            else:
                mark.append((i[:1]))
            result = []
            s = len(set(mark))
            if s == 1:
                garde.append(i.split('。')[0] + label[1])
            elif s == 2:
                ls1 = two_word(mark, result)
                if i[:1] == ls1[0]:
                    garde.append(i.split('。')[0] + label[1])
                else:
                    garde.append(i.split('。')[0] + label[2])
            elif s == 3:
                ls1 = two_word(mark, result)
                if i[:1] == ls1[0]:
                    garde.append(i.split('。')[0] + label[1])
                elif i[:1] == ls1[1]:
                    garde.append(i.split('。')[0] + label[2])
                else:
                    garde.append(i.split('。')[0] + label[3])
            elif s == 4:
                ls1 = two_word(mark, result)
                if i[:1] == ls1[0]:
                    garde.append(i.split('。')[0] + label[1])
                elif i[:1] == ls1[1]:
                    garde.append(i.split('。')[0] + label[2])
                elif i[:1] == ls1[2]:
                    garde.append(i.split('。')[0] + label[3])
                else:
                    garde.append(i.split('。')[0] + label[4])
            else:
                pass


def two_word(ls, ls1):
    for j in ls:
        if j not in ls1:
            ls1.append(j)
    return ls1


def three_word(ls, ls1):
    for j in ls:
        if j not in ls1:
            ls1.append(j)
    return ls1


def four_word(ls, ls1):
    for j in ls:
        if j not in ls1:
            ls1.append(j)
    return ls1


def creat_role():
    basic = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
    '''添加中文序号'''
    for chin in basic:
        one_characters.append(chin)
        interfere.append(chin)
        first_title.append(chin + '、')
        three_characters.append(f'({chin})')
        three_characters.append(f'({chin})')
    for chin1 in basic[:-1]:
        two_characters.append(basic[-1] + chin1)
        first_title1.append(basic[-1] + chin1 + '、')
        four_characters.append(f'({basic[-1]}{chin1})')
        four_characters.append(f'({basic[-1]}{chin1})')
    for chin2 in basic[1:-1]:
        two_characters.append(chin2 + basic[-1])
        first_title1.append(chin2 + basic[-1] + '、')
        four_characters.append(f'({chin2}{basic[-1]})')
    for chin3 in basic[1:-1]:
        for chin4 in basic[:-1]:
            three_characters.append(chin3 + '十' + chin4)
            first_title2.append(chin3 + '十' + chin4 + '、')
            five_characters.append(f'({chin3}十{chin4})')
            five_characters.append(f'({chin3}十{chin4})')

    '''添加数字序号'''
    for num in range(1, 10):
        one_characters.append(str(num))
        three_characters.append(f'({str(num)})')
        three_characters.append((f'({str(num)})'))
        number1.append(num)
    for num in range(10, 100):
        two_characters.append(str(num))
        four_characters.append(f'({str(num)})')
        four_characters.append(f'({str(num)})')
        number2.append(num)

    '''添加英文序号'''
    for letter in range(97, 123):
        one_characters.append(chr(letter))
        three_characters.append(f'({chr(letter)})')
        three_characters.append(f'({chr(letter)})')
        spell.append(chr(letter))
    for letter1 in range(65, 91):
        one_characters.append(chr(letter1))
        three_characters.append(f'({chr(letter1)})')
        three_characters.append(f'({chr(letter1)})')
        spell.append(chr(letter1))

    '''添加年份'''
    for i in range(1951, 2101):
        year.append(str(i))


if __name__ == '__main__':
    main()


代码解析

  1. 初始化判断依据:我们定义了许多列表来存储不同类型的序号和干扰字符,如one_characterstwo_characters等。这些列表用于后续判断哪些是标题。

  2. 读取文档内容read_data函数用于读取Word文档的内容,并将加粗的文本标记为标题候选。

  3. 提取标题get_title函数根据一定规则从读取的内容中提取出可能的标题。

  4. 分类标题get_second_title函数进一步细分标题的层级,并添加相应的标签(如<first><second>等)。

  5. 创建角色create_rolecreate函数初始化标题判断依据,包括中文、数字、英文序号等。

  6. 去重OrderedDict函数将重复添加的标题去掉。

项目体验

你可以在我的Gitee仓库中找到完整的项目代码,并下载到本地进行体验。点击以下链接访问项目:

Gitee仓库地址

希望这个教程对你有所帮助,如果有任何问题,欢迎在评论区留言讨论。


http://www.niftyadmin.cn/n/5536402.html

相关文章

如何选择快手矩阵系统:打造高效短视频营销的指南

快手作为中国领先的短视频社交平台&#xff0c;为内容创作者和品牌提供了广阔的展示舞台。为了更高效地管理和扩展在快手上的影响力&#xff0c;快手矩阵系统成为了一个重要的工具。本文将指导您如何选择一个合适的快手矩阵系统&#xff0c;以优化您的内容管理和营销策略。 快…

2-1 概率论基础讲解

2-1 概率论基础讲解 主目录点这里 概率论是集中研究概率和随机现象的数学分支&#xff0c;是研究随机性或不确定性等现象的学科。主要研究对象是随机事件、随机变量、随机过程。 基本概念 随机概念 随机实验&#xff1a;对自然现象进行的一次观察或一次科学实验 基本事件&…

在window上搭建docker

1、打开Hyper-V安装 在地址栏输入控制面板&#xff0c;然后回车 勾选Hyper-V安装&#xff0c;如果没有找到Hyper-V&#xff0c;那么请走第2步 2、如果没有Hyper-V(可选&#xff09;第一步无法打开 家庭版本需要开启Hyper-V 创建一个文本文档&#xff0c;后缀名称为.bat.名称…

掌握电路交换与分组交换:计算机网络的核心技术

计算机网络是现代信息社会的基石&#xff0c;而交换技术是实现网络通信的核心。本文将详细介绍两种典型的交换方式&#xff1a;电路交换和分组交换&#xff0c;帮助基础小白快速掌握这两种技术的基本概念和区别。 什么是电路交换&#xff1f; 电路交换&#xff08;Circuit Swi…

理解 React 中的 API 封装、自定义 Hooks、组件、独立模块与 Context

在现代前端开发中&#xff0c;React 提供了多种方法来组织和管理代码。这些方法包括 API 封装、自定义 Hooks、组件、独立模块和 Context。理解它们的区别和联系&#xff0c;可以帮助我们编写更清晰、更模块化的代码。 1. API 封装 目的&#xff1a;处理与后端服务的通信逻辑…

状态模式在金融业务中的应用及其框架实现

引言 状态模式&#xff08;State Pattern&#xff09;是一种行为设计模式&#xff0c;它允许对象在内部状态改变时改变其行为。状态模式通过将状态的相关行为分离到独立的状态类中&#xff0c;使得状态转换更加明确和简洁。在金融业务中&#xff0c;状态模式可以用于实现交易状…

WPS中制作甘特图的详细教程

网上没几个详细说怎么在WPS中制作甘特图的&#xff0c;我自己整理了一下详细教程&#xff0c;最终效果如下图所示&#xff1a; 1.写好需要展示的项目相关信息&#xff0c;如下图所示&#xff1a; #####这个进度的百分比渐变效果这样设置就行了 2.现在我们需要计算已用时间和剩…

02-android studio实现下拉列表+单选框+年月日功能

一、下拉列表功能 1.效果图 2.实现过程 1&#xff09;添加组件 <LinearLayoutandroid:layout_width"match_parent"android:layout_height"wrap_content"android:layout_marginLeft"20dp"android:layout_marginRight"20dp"android…