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

如何用Camelot PDF解析器处理含表格与非表格数据的PDF?

解决Camelot仅提取PDF表格、忽略非表格内容的问题

Camelot是专注于PDF表格提取的工具,本身不支持提取非表格文本。要同时获取PDF中的表格和非表格内容,需要搭配通用PDF文本提取库(比如pdfplumber),将两者的提取结果合并。

修改后的完整代码

from langchain.document_loaders.csv_loader import CSVLoader
import camelot
import uuid
from camelot.core import TableList
from collections import namedtuple
import pdfplumber

Document = namedtuple('Document', ['page_content', 'metadata'])

def export_tables_as_csv(filepath):
    tables = camelot.read_pdf(filepath, backend="ghostscript")
    # 批量导出所有表格为CSV
    tables.export("tables.csv", f="csv", compress=True)

def generate_random_filename():
    return str(uuid.uuid4())

def get_non_table_text(page, table_bboxes):
    """从pdfplumber页面中剔除表格区域,提取非表格文本"""
    non_table_text = ""
    page_width = page.width
    page_height = page.height

    # 遍历页面字符,过滤表格区域内的内容
    for char in page.chars:
        char_x = char['x0']
        # 转换坐标:pdfplumber原点在左下角,Camelot在左上角
        char_y = page_height - char['top']
        in_table = False
        for bbox in table_bboxes:
            # bbox格式:(x1, y1, x2, y2),左上角为原点
            if bbox[0] <= char_x <= bbox[2] and bbox[1] <= char_y <= bbox[3]:
                in_table = True
                break
        if not in_table:
            non_table_text += char['text']
    return non_table_text.strip()

def formChunksForTable(filepath=None, file_type=None, url=None):
    try:
        if not filepath:
            print("Error: Filepath is missing.")
            return []

        all_docs = []
        # 用Camelot提取所有页面的表格
        tables = camelot.read_pdf(filepath, backend="ghostscript", flavor='stream', pages='all')
        
        # 用pdfplumber提取非表格文本
        with pdfplumber.open(filepath) as pdf:
            for page_num, page in enumerate(pdf.pages, start=1):
                # 获取当前页的表格边界框
                page_tables = [table for table in tables if table.page == page_num]
                table_bboxes = [table._bbox for table in page_tables]
                
                # 提取并添加非表格文本
                non_table_content = get_non_table_text(page, table_bboxes)
                if non_table_content:
                    metadata = {'source': f'non-table-page-{page_num}'}
                    doc = Document(non_table_content, metadata)
                    all_docs.append(doc)
        
        # 处理表格内容,转换为Document对象
        if isinstance(tables, TableList):
            for table in tables:
                if table.df is not None and not table.df.empty:
                    for row_idx, row in enumerate(table.df.values):
                        page_content = ' '.join(str(cell) for cell in row)
                        metadata = {'source': f'table-page-{table.page}-row-{row_idx+1}'}
                        doc = Document(page_content, metadata)
                        all_docs.append(doc)
                else:
                    print(f"Warning: Table on page {table.page} is empty.")

        if not all_docs:
            print("No valid content (tables or non-table text) found in the PDF.")
        return all_docs
    except Exception as e:
        print(f"Error: {e}")
        return []

关键说明

  1. 坐标适配:pdfplumber与Camelot的坐标原点不同,通过转换字符y坐标,确保准确识别表格区域并过滤。
  2. 非文本过滤:遍历页面每个字符,仅保留表格区域外的内容,避免重复提取表格内的文本。
  3. 结果统一:将表格行和非表格文本都封装为Document对象,保持输出格式一致,方便后续处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:12:12