前言 前段时间有小伙伴问二狗,怎么把一个Word文档的题库,写一个python脚本提取到Excel里。由于数据全是选择题,且文本很有规律,不是很复杂。所以今天二狗就通过本篇文章来分享下二狗的思路和代码。 word文档数据 提取为Excel的格式编程环境 1。文中电脑操作系统:win10 2。文中所使用的python模块: (1)。os(python自带模块,不需要pip安装) (2)。re(python自带模块,不需要pip安装) (3)。docx(第三方模块,需要pip安装) 安装命令:pipinstallihttps: pypi。tuna。tsinghua。edu。cnsimplepythondocx 注意:我们这次要用到的第三方库,就是专门为docx格式的word文档而生的。如果你手头需要处理的是doc格式的word文档,你可以打开word,将其另存为docx的格式。【注意word97以上版本支持存储docx文件】 (4)。openpyxl(第三方模块,需要pip安装) 安装命令:pipinstallihttps: pypi。tuna。tsinghua。edu。cnsimpleopenpyxl 3。文中数据源文件:选择题。docx(如果需要,请后台私信) 4。文中所使用的IDE:VSCODE(安装Jupyter插件)文档数据结构剖析及代码思路 文档结构 (1)提取答案:由于答案是红色标记的,我们可以读取每一段落的样式,红色的段落就是答案。 分题 (2)分题:这个稍微有点复杂,二狗通过处理每一题前面的题号,来进行的,具体详见代码。 一行2选项 (3)一行2选项:通过split来分割,具体详见代码。代码拆检importosimportreimportdocximportopenpyxlnowpathos。getcwd()获取当前ipynb文件的路径docfile选择题。docx要提取的doc文件名excelfile选择题。xlsx保存为Excel的文件名wbopenpyxl。Workbook()实例化Excel对象wswb。active创建Excel活动表格tabhead〔序号,题目,选项1,选项2,选项3,选项4,答案〕定义Excel表头ws。append(tabhead)表头写入ExcelstartflagTrue设置开始状态contentlist〔〕初始化内容列表defjionpath(filepath,filename):功能:拼接文件路径:paramfilepath:固定参数,定义拼接的文件路径:paramfilename:固定参数,定义拼接的文件名称:return:返回拼接好的文件路径returnos。path。join(filepath,filename) 这里二狗定义了一个无聊的函数docdocx。Document(jionpath(filepathnowpath,filenamedocfile))。paragraphs读取word文档。doc文件如是。docx文件需把文件另存为。doc文件 读取docx文档,得到一个段落列表。 段落列表forcontentinfilter(lambdax:bool(x。text),doc〔1:〕):遍历段落列表rowcontent。text。strip(试题)去除每一题的试题2字rowlistre。split(rdW,row)正则切割段落文本 doc〔1:〕从第二行开始读取,不读取第一行的大标题 filter(lambdax:bool(x。text),doc〔1:〕)这里是过滤为空值的段落。 过滤效果 没有过滤的效果可以看见明显空值 strip和正则切割后的效果ifrowlist〔1:〕:判断切割后的列表的第一个元素,是否有值Ture为题目False为答案选项ifstartflag:判断是否为第一行contentlistrowlist〔1:〕如果是第一行就题目添加进空列表contentliststartflagFalse重制startflag为Falseelse:如果不是第一行contentlistanswer把answer答案列表添加进contentlistcontentlist。insert(0,number)contentlist列表里第一个位置插入序号ws。append(contentlist)把contentlist列表写入Excel里number1更新下一题的序号contentlist〔〕重置contentlist列表为空,准备添加下一题contentlistrowlist〔1:〕把题目添加进空列表contentlistelse:这里利用python的切片机制rowlist里只有一个元素时rowlist〔1:〕切片会返回rowlist〔i。strip()foriinre。split(rs{4},rowlist〔0〕)ifi〕处理一行2答案选项的情况contentlistrowlist把ABCD选项文本添加进contentlist 超过列表长度的切片方法会返回空列表 处理一行2个答案选项的效果 ifrowlist〔1:〕超过列表长度的切片方法会返回空列表不会抛出异常forrunincontent。runs:遍历每个段落的文本样式找的为红色的答案answercolorstr(run。font。color。rgb)获取每个段落的字体颜色ifanswercolorFF0000:判断此段落的文字是否为红色answerre。findall(r〔AD〕{1},run。text)提取答案项对应的字母break停止遍历每个段落的文本样式 找到答案项 此处的break只打破forrunincontent。runs的循环else:forcontentinfilter(lambdax:bool(x。text),doc〔1:〕)循环结束时contentlistanswer把answer答案列表添加进contentlistcontentlist。insert(0,number)contentlist列表里第一个位置插入序号ws。append(contentlist)最后一题写入EXcel里wb。save(jionpath(nowpath,excelfile))保存文件 因为二狗写的脚本,是通过处理下一题时来保存的上一题,所以最后一题的保存是要单独处理一下。完整代码importosimportreimportdocximportopenpyxlnowpathos。getcwd()获取当前ipynb文件的路径docfile选择题。docx要提取的doc文件名excelfile选择题。xlsx保存为Excel的文件名wbopenpyxl。Workbook()实例化Excel对象wswb。active创建Excel活动表格tabhead〔序号,题目,选项1,选项2,选项3,选项4,答案〕定义Excel表头ws。append(tabhead)表头写入ExcelstartflagTrue设置开始状态contentlist〔〕初始化内容列表defjionpath(filepath,filename):功能:拼接文件路径:paramfilepath:固定参数,定义拼接的文件路径:paramfilename:固定参数,定义拼接的文件名称:return:返回拼接好的文件路径returnos。path。join(filepath,filename)docdocx。Document(jionpath(filepathnowpath,filenamedocfile))。paragraphs读取word文档。doc文件如是。docx文件需把文件另存为。doc文件number1初始化序号forcontentinfilter(lambdax:bool(x。text),doc〔1:〕):遍历段落列表rowcontent。text。strip(试题)去除每一题的试题2字rowlistre。split(rdW,row)正则切割段落文本ifrowlist〔1:〕:判断切割后的列表的第一个元素,是否有值Ture为题目False为答案选项ifstartflag:判断是否为第一行contentlistrowlist〔1:〕如果是第一行就题目添加进空列表contentliststartflagFalse重制startflag为Falseelse:如果不是第一行contentlistanswer把answer答案列表添加进contentlistcontentlist。insert(0,number)contentlist列表里第一个位置插入序号ws。append(contentlist)把contentlist列表写入Excel里number1更新下一题的序号contentlist〔〕重置contentlist列表为空,准备添加下一题contentlistrowlist〔1:〕把题目添加进空列表contentlistelse:这里利用python的切片机制rowlist里只有一个元素时rowlist〔1:〕切片会返回rowlist〔i。strip()foriinre。split(rs{4},rowlist〔0〕)ifi〕处理一行2答案选项的情况contentlistrowlist把ABCD选项文本添加进contentlistforrunincontent。runs:遍历每个段落的文本样式找的为红色的答案answercolorstr(run。font。color。rgb)获取每个段落的字体颜色ifanswercolorFF0000:判断此段落的文字是否为红色answerre。findall(r〔AD〕{1},run。text)提取答案项对应的字母break停止遍历每个段落的文本样式else:forcontentinfilter(lambdax:bool(x。text),doc〔1:〕)循环结束时contentlistanswer把answer答案列表添加进contentlistcontentlist。insert(0,number)contentlist列表里第一个位置插入序号ws。append(contentlist)最后一题写入EXcel里wb。save(jionpath(nowpath,excelfile))保存文件结语 以上汇报完毕,下篇文章再见。(如需文中数据资料请后台私信)