如何按阅读顺序输出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)
代码说明
- 调用Textract:指定
LAYOUT和TABLES特征,确保获取元素的位置信息和表格结构。 - 处理表格:将表格单元格按行、列排序,转换为CSV格式的字符串,并用
[Table]标识区分。 - 收集元素:按页面分组,收集所有文本行和处理后的表格,记录每个元素的垂直位置(
Top坐标)。 - 排序输出:对每个页面的元素按
Top坐标从小到大排序(符合从上到下的阅读顺序),最后拼接成完整字符串。
原代码问题原因
textract-trp库中,page.lines和page.tables是独立的集合,遍历顺序是先所有文本行再所有表格,自然无法保留原顺序。textractor的get_string方法默认输出顺序并非基于元素位置,导致表格与文本行顺序颠倒。
内容的提问来源于stack exchange,提问作者diegofigueroa79
相关产品推荐
相关产品推荐

