我的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到达了这些子元素 但是我得到一个错误,这些是'property'类型的,所以我无法访问它们上的文本或对其进行迭代(TypeError:'property'对象不可迭代)。
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)
然后我想捕获文本并将其附加到字符串中以进行进一步处理。
所以我的问题是,如何访问子文本元素并从中提取文本。
我花了很多时间浏览文档和源代码,但无法弄清楚。任何帮助将不胜感激。
答案 0 :(得分: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 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
答案 1 :(得分: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 :(得分:0)
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”的第二个循环并直接进入递归函数。
为了便于阅读,我将发布整个固定片段。
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)