python逐段读取docx文件中的图片(高中信息技术题库系统)

最近做了一个”浙江省高中信息技术高考题库系统”,后台用django框架,前端vue.js。其中有个功能模块就是把练习题目docx格式,批量导入数据库。具体做法就是前端上传word版的题目,后台批量逐段读取里面的题目,包括图片。

网络上搜索到的大部分的一次性读取docx中的所有图片。这样在我系统里行不通,因为我需要某段的图片属于哪一题的。图片要跟相应的题目一起写入数据库。

先上图吧

python逐段读取docx文件中的图片(高中信息技术题库系统)

最终的目标就是把题目的内容、答案、解析、图片、题型等提取出来,其中图片以base64格式编码成字符,统一json格式,把多个题目的信息返回给前端确认题目时候识别正确,以列表形式返回给前端;形式如下:

[{“content”:”按照二叉树的定义,具有3个节点的二叉树形态有( )A.3种B.4种C.5种D.6种”,”answer”:”C”,”explain”:”略”,”type”:”选择题”,”pictures”:”data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAwADAAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAw”}]

因为题库系统中题目的模型如下:

class Questions(models.Model):
    QUESTION_TYPE_CHOICES = (
        ('选择题','选择题'),
        ('填空题','填空题'),
        ('简答题','简答题')
    )
    DIFFICULTY_LEVEL_CHOICES = (
        ('入门', '入门'),
        ('中级', '中级'),
        ('高级', '高级')
    )
    content = models.CharField(max_length=1000,verbose_name='内容')
    # overview = models.CharField(max_length=100,verbose_name='内容概述,取内容的前25个字符',default='')
    answer = models.CharField(max_length=200,verbose_name='正确答案')
    explain = models.CharField(max_length=200,verbose_name='解析')
    reference = models.CharField(max_length=20,verbose_name='引用哪里',help_text="比如引用5年高考3年模拟,写作53")
    type = models.CharField(verbose_name='题型',max_length=10, choices=QUESTION_TYPE_CHOICES)
    difficulty_level = models.CharField(verbose_name='难度', max_length=10, choices=DIFFICULTY_LEVEL_CHOICES,default=DIFFICULTY_LEVEL_CHOICES[0][0])
    owner = models.ForeignKey(User, verbose_name='录入者',on_delete=models.CASCADE,related_name="questions")
    add_time = models.DateTimeField(auto_now_add=True, verbose_name='录入时间')
    last_edit_time = models.DateTimeField(auto_now_add=True, verbose_name='修改时间')
    open_level = models.CharField(verbose_name='开放程度',choices=OPEN_LEVEL_CHOICES, max_length=10, default=OPEN_LEVEL_CHOICES[0][0])
    #tags = TaggableManager()
    top = models.BooleanField(default=False, verbose_name='置顶')
    knowledgepoint = models.ForeignKey(KnowledgePoint,on_delete=models.CASCADE,verbose_name='知识点', related_name="questions")
    order = OrderField(blank=True, for_fields=['knowledgepoint'], verbose_name='排序序号',
                       help_text="决定各节之间的排序序号,升序排序比如第一章为1,第二章为2;1.1为1;1.3为了3")
    pictures = models.CharField(max_length=200000, blank=True)

    class Meta:
        verbose_name = '题目'
        verbose_name_plural = verbose_name
        ordering = ['order']
    def __str__(self):
        return self.content[len(self.content)//10]

前端确认无误或者修改后,把所有题目信息的列表重新post给后端,写入数据库

言归正传:其中如何逐段读取word内的图片

多说无益,先附上代码:

import docx
from docx.document import Document
from docx.text.paragraph import Paragraph
from docx.image.image import Image
from docx.parts.image import ImagePart
from docx.oxml.shape import CT_Picture
from PIL import Image
from io import BytesIO
import sys

def get_picture(document: Document, paragraph:Paragraph):
"""
    document 为文档对象
    paragraph 为内嵌图片的段落对象,比如第1段内
"""
    result_list=[]
    img_list = paragraph._element.xpath('.//pic:pic')
    if len(img_list)==0 or not img_list:
        return
    for i in range(len(img_list)):
        img: CT_Picture = img_list[i]
        embed = img.xpath('.//a:blip/@r:embed')[0]
        related_part: ImagePart = document.part.related_parts
        image: Image = related_part.image
        result_list.append(image)
    return result_list

if __name__ =="__main__":
    d = docx.Document('test.docx')
    for i in range(len(d.paragraphs)):
        paragraph = d.paragraphs[i]
        image_list = get_picture(d, paragraph)
        if not image_list:
            continue
        for image in image_list:
            if image:
                # 后缀
                ext = image.ext
                # 二进制内容
                blob = image.blob
                # 显示图片
                Image.open(BytesIO(blob)).show()

效果如下:依次逐行读每张图片,并显示出来。这里只是测试,跟项目结合读取题目内容的部分空,下次再发出来

python逐段读取docx文件中的图片(高中信息技术题库系统)

解说下源代码的关键地方:

import docx
from docx.document import Document #读取word的docx文件
from docx.text.paragraph import Paragraph #读取段落
from docx.image.image import Image #读取图片

for i in range(len(d.paragraphs)):
paragraph = d.paragraphs[i] #逐行读取第i自然段

img_list = paragraph._element.xpath(‘.//pic:pic’) #读取该自然段内的所有图片,返回列表

for i in range(len(img_list)):
img: CT_Picture = img_list[i]
embed = img.xpath(‘.//a:blip/@r:embed’)[0] #读取该自然段内的内嵌图片

if image:

后缀

ext = image.ext

二进制内容

blob = image.blob #blob方法获取二进制流文件

显示图片

Image.open(BytesIO(blob)).show() #BytesIO 转成字节流显示出来

本文章引用以下:

如何使用Python提取Word文档中的图片? – 知乎

Original: https://blog.csdn.net/zhuwoqing/article/details/124854914
Author: 智者无言
Title: python逐段读取docx文件中的图片(高中信息技术题库系统)



相关阅读

Title: 皮尔逊相关系数python实现

一、皮尔逊相关系数

常见公式:

python逐段读取docx文件中的图片(高中信息技术题库系统)
公式转换:
python逐段读取docx文件中的图片(高中信息技术题库系统)
有关皮尔逊相关系数的具体内容可以在之前的文章中看到。
[En]

Specific content related to Pearson correlation coefficient can be seen in a previous article.

相似度计算(2)——皮尔逊相关系数

; 二、python实现

方法1:直接按公式算

import numpy as np

x=np.array([1,3,5])
y=np.array([1,3,4])
n=len(x)

sum_xy = np.sum(np.sum(x*y))
sum_x = np.sum(np.sum(x))
sum_y = np.sum(np.sum(y))
sum_x2 = np.sum(np.sum(x*x))
sum_y2 = np.sum(np.sum(y*y))
pc = (n*sum_xy-sum_x*sum_y)/np.sqrt((n*sum_x2-sum_x*sum_x)*(n*sum_y2-sum_y*sum_y))

print(pc)

方法2:调用numpy中的corrcoef方法

方法:
corrcoef(x, y=None, rowvar=True, bias=np._NoValue, ddof=np._NoValue)

参数:
x:array_like,包含多个变量和观测值的1-D或2-D数组,x的每一行代表一个变量,每一列都是对所有这些变量的单一观察。
y:array_like,可选,另外一组变量和观察,y具有与x相同的形状。
rowvar:bool, 可选,如果rowvar为True(默认值),则每行代表一个变量,并在列中显示。否则,转换关系:每列代表一个变量,而行包含观察。
bias:_NoValue,可选,没有效果,请勿使用
ddof:_NoValue,可选,没有效果,请勿使用

返回值:
R : ndarray,变量的相关系数矩阵。

代码:

import numpy as np

x=np.array([1,3,5])
y=np.array([1,3,4])

pc=np.corrcoef(x,y)

print(pc)

方法3:调用scipy.stats中的pearsonr方法

方法:
pearsonr(x, y)

参数:
x:(N,) array_like,Input array。
y:(N,) array_like,Input array。

返回值:
r : float,皮尔逊相关系数,[-1,1]之间。
p-value : float,Two-tailed p-value(双尾P值)。
注: p值越小,表示相关系数越显著,一般p值在500个样本以上时有较高的可靠性。可以理解为显著性水平。

代码:

from scipy.stats import pearsonr
import numpy as np

x=np.array([1,3,5])
y=np.array([1,3,4])

pc = pearsonr(x,y)

print("相关系数:",pc[0])
print("显著性水平:",pc[1])

方法4:调用pandas.Dataframe中的corr方法

方法:
def corr(self,method,min_periods)

参数:
method:可选值为{‘pearson’, ‘kendall’, ‘spearman’}
pearson:皮尔逊相关系数
kendall:肯德尔等级相关系数
spearman:斯皮尔曼等级相关系数
min_periods:样本最少的数据量,最少为1。

返回值:
返回值:各类型之间的相关系数DataFrame表格。

代码:

import pandas as pd

data=pd.DataFrame({"x":[1,3,5],"y":[1,3,4]})

print(data.corr("pearson"))

Original: https://blog.csdn.net/weixin_43876625/article/details/123919665
Author: 回一幻
Title: 皮尔逊相关系数python实现

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/287254/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

最近整理资源【免费获取】:   👉 程序员最新必读书单  | 👏 互联网各方向面试题下载 | ✌️计算机核心资源汇总