【问题标题】:How to extract text from a text shape within a Group Shape in powerpoint, using python-pptx.如何使用 python-pptx 从 powerpoint 中的组形状中的文本形状中提取文本。
【发布时间】:2019-01-13 01:25:00
【问题描述】:

我的 PowerPoint 幻灯片有许多组形状,其​​中有子文本形状。

之前我使用过这段代码,但它不能处理组形状。

for eachfile in files:
prs = Presentation(eachfile)

textrun=[]
for slide in prs.slides:
    for shape in slide.shapes:
        if hasattr(shape, "text"):
            print(shape.text)
            textrun.append(shape.text)
new_list=" ".join(textrun)
text_list.append(new_list)

我正在尝试从这些子文本框中提取文本。我已经设法使用 GroupShape.shape 到达这些子元素 但我得到一个错误,这些是“属性”类型的,所以我无法访问文本或迭代它们(TypeError:“属性”对象不可迭代)。

from pptx.shapes.group import GroupShape
from pptx import Presentation
for eachfile in files:
prs = Presentation(eachfile)

textrun=[]
for slide in prs.slides:
    for shape in slide.shapes:
        for text in GroupShape.shapes:
            print(text)

然后我想捕获文本并附加到字符串以进行进一步处理。

所以我的问题是,如何访问子文本元素并从中提取文本。

我花了很多时间查看文档和源代码,但一直无法弄清楚。任何帮助将不胜感激。

【问题讨论】:

    标签: python text powerpoint python-pptx


    【解决方案1】:

    我认为你需要这样的东西:

    from pptx.enum.shapes import MSO_SHAPE_TYPE
    
    for slide in prs.slides:
        # ---only operate on group shapes---
        group_shapes = [
            shp for shp in slide.shapes
            if shp.shape_type == MSO_SHAPE_TYPE.GROUP
        ]
        for group_shape in group_shapes:
            for shape in group_shape.shapes:
                if shape.has_text_frame:
                    print(shape.text)
    

    组形状包含其他形状,可通过其.shapes 属性访问。它本身有一个.text 属性。因此,您需要迭代组中的形状并从每个形状中获取文本。

    请注意,此解决方案仅深入一层。递归方法可用于深度优先遍历树,并从包含组的组中获取文本(如果有的话)。

    另请注意,并非所有形状都有文本,因此您必须检查 .has_text_frame 属性以避免引发异常,例如图片形状。

    【讨论】:

      【解决方案2】:

      较早的答案遗漏了一些更深层次的“组中组”案例。组形状可能包含许多级别的形状,包括组形状。因此,在许多现实生活中,需要在组形状中进行递归搜索。

      上一个答案仅解析其中的一些(直至第二层组形状)。但即使是该层组形状也可能包含更多组。所以我们需要一个迭代搜索策略。这最好通过重用上面的代码来显示,保留第一部分:

      from pptx.shapes.group import GroupShape
      from pptx import Presentation
      for eachfile in files:
      prs = Presentation(eachfile)
      
      textrun=[]
      for slide in prs.slides:
          for shape in slide.shapes:
      

      那么我们需要将“for text in GroupShape.shapes:”测试替换为对递归部分的调用:

          textrun=checkrecursivelyfortext(slide.shapes,textrun)
      

      并且还插入一个新的函数递归函数定义(就像在 import 语句之后)。为了便于比较,插入的函数使用与上面相同的代码,只是添加了递归部分:

      def checkrecursivelyfortext(shpthissetofshapes,textrun):
          for shape in shpthissetofshapes:
              if shape.shape_type == MSO_SHAPE_TYPE.GROUP:
                  textrun=checkrecursivelyfortext(shape.shapes,textrun)
              else:
                  if hasattr(shape, "text"):
                      print(shape.text)
                      textrun.append(shape.text)
          return textrun
      

      【讨论】:

      • 我在下面发布了对此答案的修复。
      【解决方案3】:

      Mats Bengtsson 的答案是正确的,除了逻辑错误中的一个小错误会导致它重新循环对象、一些非 Python 命名和缺少导入。

      错误在这里:

      for slide in prs.slides:
          for shape in slide.shapes:
              textrun = checkrecursivelyfortext(slide.shapes,textrun)
      

      由于他创建的函数循环遍历 slide.shapes 中的所有形状,最终结果是对于幻灯片上的每个形状,它将递归遍历幻灯片上的所有形状!

      这个修复很简单,只要去掉“for shape in slide.shapes”的第二个循环,直接进入递归函数即可。

      为了便于阅读,我将发布整个固定的 sn-p。

      from pptx.shapes.group import GroupShape
      from pptx.enum.shapes import MSO_SHAPE_TYPE
      from pptx import Presentation
      
      def check_recursively_for_text(this_set_of_shapes, text_run):
          for shape in this_set_of_shapes:
              if shape.shape_type == MSO_SHAPE_TYPE.GROUP:
                  check_recursively_for_text(shape.shapes, text_run)
              else:
                  if hasattr(shape, "text"):
                      print(shape.text)
                      text_run.append(shape.text)
          return text_run
      
      
      for eachfile in files:
          prs = Presentation(eachfile)
          text_run=[]
          for slide in prs.slides:
              text_run = check_recursively_for_text(slide.shapes, text_run)
          
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-09-24
        • 2021-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多