parse_blocks()
simply returns all blocks found in the post content, so for what you’re trying to get, you could use a function which calls itself recursively like so:
function my_find_heading_blocks( $blocks ) {
$list = array();
foreach ( $blocks as $block ) {
if ( 'core/heading' === $block['blockName'] ) {
// add current item, if it's a heading block
$list[] = $block;
} elseif ( ! empty( $block['innerBlocks'] ) ) {
// or call the function recursively, to find heading blocks in inner blocks
$list = array_merge( $list, my_find_heading_blocks( $block['innerBlocks'] ) );
}
}
return $list;
}
// Sample usage:
$post = get_post();
$blocks = parse_blocks( $post->post_content );
$headings = my_find_heading_blocks( $blocks );