美文网首页
python提取word文件中的图片,并上传阿里云OSS,返回h

python提取word文件中的图片,并上传阿里云OSS,返回h

作者: 梦想橡皮擦 | 来源:发表于2022-01-19 07:55 被阅读0次

    该需求是一个真实的实战需求,如果你的公司在做题库类的系统,一定会涉及该方面的内容,所以收藏起来吧。

    需求简单描述如下所示:

    1. 提取 Word(为了便于解决,统一格式为 docx)中的题干/选项图片;
    2. 将其传递到云 OSS 上,并返回图片地址;
    3. 部分场景,需要将其拼接为 HTML 的 img 标签进行返回。

    实操环节

    首先你需要准备好云OSSAccessKeyIdAccessKeySecret ,这两个值一般由运维工程师提供给你,如果你的公司比较小,没有运维岗位,那就需要自己去申请并进行配置啦。

    云 OSS 的购买和设置的流程非常简单,创建一个 Bucket 之后,就可以使用了。

    然后点击创建好的 Bucket ,进行权限设置,选择公共读即可。

    接下来在 Python 文件中编写如下代码,并测试是否可以返回 Bucket 对象,下述的字符串一定要写准确,任意内容错误都会报错,导致 oss 无法链接。

    AccessKeyId = '你的 AccessKeyId'
    AccessKeySecret = '你的 AccessKeySecret'
    oos_auth = oss2.Auth(AccessKeyId, AccessKeySecret)
    endpoint = 'http://oss-cn-beijing.aliyuncs.com'
    
    bucket = oss2.Bucket(oos_auth, endpoint, 'Bucket 名称')  
    print(bucket)
    

    上述字符串的值,可以在云 OSS 的概览中找到,如下图所示。

    接下来就进入 Word 图片的环节,读取文件依旧使用第三方模块, python-docx

    在正式开始前,需要准备好一个测试用的 Word 文档,可以参考下图设置 Word 文档的内容。

    首先通过 python-docx 读取文档中的所有行 paragraphs ,使用如下代码:

    import oss2
    import time
    
    from docx import Document
    
    def get_questions():
        document = Document(docx='测试 Word 文档.docx')
        for p in document.paragraphs:
            print(p.text)
    
    if __name__ == '__main__':
        get_questions()
    

    上述代码重点为 document.paragraphs ,调用该属性将逐段落返回文档内容,然后再通过对象的 .text 属性,输出里面的文字。

    python提取word文件中的图片,并上传阿里云OSS,返回html图片标签

    此时的代码无法获取到段落中的图片,可以使用下述代码进行提取。

    import oss2
    import time
    
    from docx import Document
    
    # 获取 Word 文档中的图片
    def get_picture(document, paragraph):
        img = paragraph._element.xpath('.//pic:pic')
        if not img:
            return
        img = img[0]
        embed = img.xpath('.//a:blip/@r:embed')[0]
        related_part = document.part.related_parts[embed]
        image = related_part.image
        return image
    
    def get_questions():
        document = Document(docx='测试 Word 文档.docx')
    
        for p in document.paragraphs:
            # 读取图片
            img = get_picture(document, p)
    
            print(img)
            if img is not None:
                # 输出图片名
                print(img.filename)
                # 输出图片后缀
                print(img.ext)
                # 输出图片的二进制流
                # print(img.blob)
            print(p.text)
    
    if __name__ == '__main__':
        get_questions()
    

    在上述代码中,最重要的函数为 get_picture() 函数,核心逻辑是由于 docx 文档是一种 xml 结构,通过 paragraph._element.xpath() 方法可以进行数据提取。

    读取数据的结果如下所示:

    python提取word文件中的图片,并上传阿里云OSS,返回html图片标签

    在上文的注释中,还存在一个图片属性 img.blob ,即读取图片的二进制流。

    拿该文件流即可写入云 OSS,然后拼接图片的访问路径,最后将其拼接到 img 标签中即可。

    import oss2
    import time
    
    from docx import Document
    
    # 获取 Word 文档中的图片
    def get_picture(document, paragraph):
        img = paragraph._element.xpath('.//pic:pic')
        if not img:
            return
        img = img[0]
        embed = img.xpath('.//a:blip/@r:embed')[0]
        related_part = document.part.related_parts[embed]
        image = related_part.image
        return image
    
    def ret_up_imgurl(image):
        blob = image.blob
        # 后缀
        ext = image.ext
    
        AccessKeyId = '你的 AccessKeyId'
        AccessKeySecret = '你的 AccessKeySecret '
        oos_auth = oss2.Auth(AccessKeyId, AccessKeySecret)
        endpoint = 'http://oss-cn-beijing.aliyuncs.com'
    
        bucket = oss2.Bucket(oos_auth, endpoint, 'Bucket 名称')  
    
        base_file_url = 'https://Bucket 名称.oss-cn-beijing.aliyuncs.com/'
        # 获取一个文件名
        file_name = str(int(time.time())) + "." + ext
        # 上传二进制流
        res = bucket.put_object(file_name, blob)
        if res.status == 200:
            # 返回标签
            img_format = '<img src="{}" />'
            return img_format.format(base_file_url + file_name)
        else:
            return False
    
    def get_questions():
        document = Document(docx='测试 Word 文档.docx')
    
        for p in document.paragraphs:
            print(p.text)
            img = get_picture(document, p)
    
            print(img)
            if img is not None:
                print(img.filename)
                print(img.ext)
                ret_up_imgurl(img.blob)
    
    if __name__ == '__main__':
        get_questions()
    

    上述代码重点部分在 bucket.put_object(file_name, blob) ,该方法将图片二进制流传递到OSS空间。

    本需求就实现到这里了,如果对你有帮助,欢迎一键三连~

    支持博主时间

    今天是持续写作的第 <font color=red>278</font> / 365 天。
    可以<font color=#04a9f4>关注</font>我,<font color=#04a9f4>点赞</font>我、<font color=#04a9f4>评论</font>我、<font color=#04a9f4>收藏</font>我啦。

    更多精彩


    相关文章

      网友评论

          本文标题:python提取word文件中的图片,并上传阿里云OSS,返回h

          本文链接:https://www.haomeiwen.com/subject/catrhrtx.html