You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按阅读顺序输出AWS Textract分析文档的表格与文本内容

问题:AWS Textract提取内容无法按原文档顺序输出

需要从PDF中提取文本和表格,并严格按照原文档的阅读顺序(文本行→表格→后续文本行)输出为单个字符串。但使用textract-trp和textractor库时,均出现顺序混乱:前者先输出所有文本行再输出表格,后者先输出表格再输出文本行,都不符合要求。

解决方案:基于元素位置排序输出

核心思路是利用AWS Textract的LAYOUT分析能力,获取每个元素(文本行、表格)的垂直位置坐标,按坐标排序后再输出内容。

代码实现

import boto3
from collections import defaultdict

def extract_content_in_order(pdf_path):
    textract = boto3.client('textract')
    
    # 读取PDF文件并调用Textract分析
    with open(pdf_path, 'rb') as document:
        response = textract.analyze_document(
            Document={'Bytes': document.read()},
            FeatureTypes=['LAYOUT', 'TABLES']
        )
    
    # 先处理所有表格,转换为结构化字符串
    table_map = {}
    for block in response['Blocks']:
        if block['BlockType'] == 'TABLE':
            table_id = block['Id']
            cells = []
            # 收集表格所有单元格信息
            for rel in block.get('Relationships', []):
                if rel['Type'] == 'CHILD':
                    for cell_id in rel['Ids']:
                        cell_block = next(b for b in response['Blocks'] if b['Id'] == cell_id)
                        cells.append({
                            'RowIndex': cell_block['RowIndex'],
                            'ColumnIndex': cell_block['ColumnIndex'],
                            'Text': cell_block['Text']
                        })
            # 按行、列排序单元格,生成CSV格式表格内容
            sorted_cells = sorted(cells, key=lambda x: (x['RowIndex'], x['ColumnIndex']))
            table_rows = []
            current_row = None
            row_cells = []
            for cell in sorted_cells:
                if cell['RowIndex'] != current_row:
                    if current_row is not None:
                        table_rows.append(','.join(row_cells))
                    row_cells = [cell['Text']]
                    current_row = cell['RowIndex']
                else:
                    row_cells.append(cell['Text'])
            if row_cells:
                table_rows.append(','.join(row_cells))
            # 封装表格内容,添加标识
            table_str = '\n'.join(table_rows)
            table_map[table_id] = {
                'Top': block['Geometry']['BoundingBox']['Top'],
                'Content': f'[Table]\n{table_str}\n[/Table]'
            }
    
    # 按页面分组收集所有元素(文本行+处理好的表格)
    page_elements = defaultdict(list)
    for block in response['Blocks']:
        page_num = block['Page']
        if block['BlockType'] == 'LINE':
            page_elements[page_num].append({
                'Top': block['Geometry']['BoundingBox']['Top'],
                'Content': block['Text']
            })
        elif block['BlockType'] == 'TABLE':
            page_elements[page_num].append(table_map[block['Id']])
    
    # 按垂直位置排序每个页面的元素,拼接最终内容
    final_content = []
    for page in sorted(page_elements.keys()):
        # 按Top坐标从小到大排序,Top值越小越靠上
        sorted_elements = sorted(page_elements[page], key=lambda x: x['Top'])
        for elem in sorted_elements:
            final_content.append(elem['Content'])
    
    return '\n'.join(final_content)

# 调用示例
if __name__ == '__main__':
    result = extract_content_in_order('my-sample.pdf')
    print(result)

代码说明

  1. 调用Textract:指定LAYOUT和TABLES特征,确保获取元素的位置信息和表格结构。
  2. 处理表格:将表格单元格按行、列排序,转换为CSV格式的字符串,并用[Table]标识区分。
  3. 收集元素:按页面分组,收集所有文本行和处理后的表格,记录每个元素的垂直位置(Top坐标)。
  4. 排序输出:对每个页面的元素按Top坐标从小到大排序(符合从上到下的阅读顺序),最后拼接成完整字符串。

原代码问题原因

  • textract-trp库中,page.lines和page.tables是独立的集合,遍历顺序是先所有文本行再所有表格,自然无法保留原顺序。
  • textractor的get_string方法默认输出顺序并非基于元素位置,导致表格与文本行顺序颠倒。

内容的提问来源于stack exchange,提问作者diegofigueroa79

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 17:53:14