PDF 处理策略

Crawl4AI 提供了专门用于处理和提取 PDF 文件内容的策略。这些策略允许您将 PDF 处理无缝集成到您的爬取工作流中,无论 PDF 是托管在线上还是存储在本地。

PDFCrawlerStrategy

概述

PDFCrawlerStrategyAsyncCrawlerStrategy 的一个实现,专为 PDF 文档设计。此策略不是将输入 URL 解释为 HTML 网页,而是将其视为指向 PDF 文件的指针。它本身不执行深度爬取或 HTML 解析,而是为专用的 PDF 抓取策略准备 PDF 源。其主要作用是识别 PDF 源(Web URL 或本地文件),并以 AsyncWebCrawler 可以处理的方式将其传递给处理管道。

使用时机

当您需要以下功能时,请使用 PDFCrawlerStrategy: - 使用 AsyncWebCrawler 处理 PDF 文件。 - 处理来自 Web URL(例如 https://example.com/document.pdf)和本地文件路径(例如 file:///path/to/your/document.pdf)的 PDF。 - 将 PDF 内容提取集成到统一的 CrawlResult 对象中,从而允许对 PDF 数据和网页数据进行一致的处理。

关键方法及其行为

  • __init__(self, logger: AsyncLogger = None):
    • 初始化策略。
    • logger:一个可选的 AsyncLogger 实例(来自 crawl4ai.async_logger),用于日志记录。
  • async crawl(self, url: str, **kwargs) -> AsyncCrawlResponse:
    • 此方法由 AsyncWebCrawlerarun 过程中调用。
    • 它接收 url(应指向一个 PDF)并创建一个最小的 AsyncCrawlResponse
    • 此响应的 html 属性通常为空或是一个占位符,因为实际的 PDF 内容处理被推迟到 PDFContentScrapingStrategy(或类似的 PDF 感知抓取策略)。
    • 它将 response_headers 设置为指示 "application/pdf",并将 status_code 设置为 200。
  • async close(self):
    • 一个用于清理策略使用的任何资源的方法。对于 PDFCrawlerStrategy,这通常是最少的。
  • async __aenter__(self) / async __aexit__(self, exc_type, exc_val, exc_tb):
    • 为策略启用异步上下文管理,允许其与 async with 一起使用。

使用示例

import asyncio
from crawl4ai import AsyncWebCrawler, CrawlerRunConfig
from crawl4ai.processors.pdf import PDFCrawlerStrategy, PDFContentScrapingStrategy

async def main():
    # 初始化 PDF 爬取器策略
    pdf_crawler_strategy = PDFCrawlerStrategy()

    # PDFCrawlerStrategy 通常与 PDFContentScrapingStrategy 结合使用
    # 抓取策略处理实际的 PDF 内容提取
    pdf_scraping_strategy = PDFContentScrapingStrategy()
    run_config = CrawlerRunConfig(scraping_strategy=pdf_scraping_strategy)

    async with AsyncWebCrawler(crawler_strategy=pdf_crawler_strategy) as crawler:
        # 使用远程 PDF URL 的示例
        pdf_url = "https://arxiv.org/pdf/2310.06825.pdf" # 来自 arXiv 的公共 PDF

        print(f"Attempting to process PDF: {pdf_url}")
        result = await crawler.arun(url=pdf_url, config=run_config)

        if result.success:
            print(f"Successfully processed PDF: {result.url}")
            print(f"Metadata Title: {result.metadata.get('title', 'N/A')}")
            # 在此处根据 PDFContentScrapingStrategy 提取的内容,对 result.markdown、result.media 等进行进一步处理。
            if result.markdown and hasattr(result.markdown, 'raw_markdown'):
                print(f"Extracted text (first 200 chars): {result.markdown.raw_markdown[:200]}...")
            else:
                print("No markdown (text) content extracted.")
        else:
            print(f"Failed to process PDF: {result.error_message}")

if __name__ == "__main__":
    asyncio.run(main())

优缺点

优点: - 使 AsyncWebCrawler 能够使用熟悉的 arun 调用直接处理 PDF 源。 - 为指定 PDF 源(URL 或本地路径)提供一致的接口。 - 抽象了源处理,允许单独的抓取策略专注于 PDF 内容解析。

缺点: - 本身不执行任何 PDF 数据提取;它严格依赖兼容的抓取策略(如 PDFContentScrapingStrategy)来处理 PDF。 - 单独使用时效用有限;其大部分价值来自于与 PDF 特定的内容抓取策略配对使用。


PDFContentScrapingStrategy

概述

PDFContentScrapingStrategyContentScrapingStrategy 的一个实现,旨在从 PDF 文档中提取文本、元数据以及可选的图像。它旨在与能够为其提供 PDF 源的爬取器策略(如 PDFCrawlerStrategy)结合使用。该策略在内部使用 NaivePDFProcessorStrategy 来执行底层 PDF 解析。

使用时机

当您的 AsyncWebCrawler(通常配置了 PDFCrawlerStrategy)需要以下功能时,请使用 PDFContentScrapingStrategy: - 从 PDF 文档中逐页提取文本内容。 - 检索 PDF 内嵌入的标准元数据(例如,标题、作者、主题、创建日期、页数)。 - 可选地,提取 PDF 页面中包含的图像。这些图像可以保存到本地目录或供进一步处理。 - 生成可以转换为 CrawlResultScrapingResult,使 PDF 内容可以以类似于 HTML Web 内容的方式访问(例如,文本在 result.markdown 中,元数据在 result.metadata 中)。

关键配置属性

初始化 PDFContentScrapingStrategy 时,您可以使用以下属性配置其行为: - extract_images: bool = False: 如果为 True,策略将尝试从 PDF 中提取图像。 - save_images_locally: bool = False: 如果为 True(并且 extract_images 也为 True),提取的图像将被保存到 image_save_dir 的磁盘上。如果为 False,图像数据可能以其他形式可用(例如 base64,取决于底层处理器),但不会由此策略保存为单独的文件。 - image_save_dir: str = None: 指定如果 save_images_locallyTrue,提取的图像应保存到的目录。如果为 None,则可能使用默认或临时目录。 - batch_size: int = 4: 定义单批处理多少 PDF 页面。这在处理非常大的 PDF 文档时对于管理内存非常有用。 - logger: AsyncLogger = None: 一个可选的 AsyncLogger 实例,用于日志记录。

关键方法及其行为

  • __init__(self, save_images_locally: bool = False, extract_images: bool = False, image_save_dir: str = None, batch_size: int = 4, logger: AsyncLogger = None):
    • 使用图像处理、批处理和日志记录的配置来初始化策略。它设置了一个内部 NaivePDFProcessorStrategy 实例,该实例执行实际的 PDF 解析。
  • scrap(self, url: str, html: str, **params) -> ScrapingResult:
    • 这是爬取器(通过 ascrap)调用的主要同步方法,用于处理 PDF。
    • url:PDF 文件的路径或 URL(由 PDFCrawlerStrategy 或类似策略提供)。
    • html:当与 PDFCrawlerStrategy 一起使用时,通常是一个空字符串,因为内容是 PDF 而不是 HTML。
    • 它首先确保 PDF 可以在本地访问(如果 url 是远程的,则将其下载到临时文件)。
    • 然后使用其内部 PDF 处理器提取文本、元数据和图像(如果已配置)。
    • 提取的信息被编译成一个 ScrapingResult 对象:
      • cleaned_html:包含 PDF 的类 HTML 表示,其中每个页面的内容通常包装在带有页码信息的 <div> 中。
      • media:一个字典,如果 extract_imagesTrue,则 media["images"] 将包含有关提取图像的信息。
      • links:一个字典,links["urls"] 可以包含在 PDF 内容中找到的 URL。
      • metadata:一个包含 PDF 元数据(例如,标题、作者、页数)的字典。
  • async ascrap(self, url: str, html: str, **kwargs) -> ScrapingResult:
    • scrap 的异步版本。在底层,它通常使用 asyncio.to_thread 在单独的线程中运行同步的 scrap 方法,以避免阻塞事件循环。
  • _get_pdf_path(self, url: str) -> str:
    • 一个私有的辅助方法,用于管理 PDF 文件访问。如果 url 是远程的(http/https),它会将 PDF 下载到临时本地文件并返回其路径。如果 url 指示是本地文件(file:// 或直接路径),它会解析并返回本地路径。

使用示例

import asyncio
from crawl4ai import AsyncWebCrawler, CrawlerRunConfig
from crawl4ai.processors.pdf import PDFCrawlerStrategy, PDFContentScrapingStrategy
import os # 用于创建图像目录

async def main():
    # 定义保存提取图像的目录
    image_output_dir = "./my_pdf_images"
    os.makedirs(image_output_dir, exist_ok=True)

    # 配置 PDF 内容抓取策略
    # 启用图像提取并指定保存位置
    pdf_scraping_cfg = PDFContentScrapingStrategy(
        extract_images=True,
        save_images_locally=True,
        image_save_dir=image_output_dir,
        batch_size=2 # 为演示起见,每次处理 2 页
    )

    # 需要 PDFCrawlerStrategy 来告诉 AsyncWebCrawler 如何“爬取” PDF
    pdf_crawler_cfg = PDFCrawlerStrategy()

    # 配置整体爬取运行
    run_cfg = CrawlerRunConfig(
        scraping_strategy=pdf_scraping_cfg # 使用我们的 PDF 抓取策略
    )

    # 使用 PDF 特定的爬取器策略初始化爬取器
    async with AsyncWebCrawler(crawler_strategy=pdf_crawler_cfg) as crawler:
        pdf_url = "https://arxiv.org/pdf/2310.06825.pdf" # 示例 PDF

        print(f"Starting PDF processing for: {pdf_url}")
        result = await crawler.arun(url=pdf_url, config=run_cfg)

        if result.success:
            print("\n--- PDF Processing Successful ---")
            print(f"Processed URL: {result.url}")

            print("\n--- Metadata ---")
            for key, value in result.metadata.items():
                print(f"  {key.replace('_', ' ').title()}: {value}")

            if result.markdown and hasattr(result.markdown, 'raw_markdown'):
                print(f"\n--- Extracted Text (Markdown Snippet) ---")
                print(result.markdown.raw_markdown[:500].strip() + "...")
            else:
                print("\nNo text (markdown) content extracted.")

            if result.media and result.media.get("images"):
                print(f"\n--- Image Extraction ---")
                print(f"Extracted {len(result.media['images'])} image(s).")
                for i, img_info in enumerate(result.media["images"][:2]): # 显示前 2 张图像的信息
                    print(f"  Image {i+1}:")
                    print(f"    Page: {img_info.get('page')}")
                    print(f"    Format: {img_info.get('format', 'N/A')}")
                    if img_info.get('path'):
                        print(f"    Saved at: {img_info.get('path')}")
            else:
                print("\nNo images were extracted (or extract_images was False).")
        else:
            print(f"\n--- PDF Processing Failed ---")
            print(f"Error: {result.error_message}")

if __name__ == "__main__":
    asyncio.run(main())

优缺点

优点: - 提供了一种从 PDF 文档中提取文本、元数据和(可选)图像的全面方法。 - 处理远程 PDF(通过 URL)和本地 PDF 文件。 - 可配置的图像提取允许将图像保存到磁盘或访问其数据。 - 与 CrawlResult 对象结构平滑集成,使 PDF 衍生的数据可以以与网络抓取数据一致的方式访问。 - batch_size 参数有助于在处理大量 PDF 页面时管理内存消耗。

缺点: - 提取质量和性能可能因 PDF 的复杂性、编码以及是基于图像(扫描)还是基于文本而有很大差异。 - 图像提取可能非常消耗资源(如果 save_images_locally 为 true,则消耗 CPU 和磁盘空间)。 - 内部依赖 NaivePDFProcessorStrategy,与更复杂的 PDF 解析库相比,它在处理非常复杂的布局、加密 PDF 或表单时可能存在局限性。扫描的 PDF 不会产生文本,除非执行 OCR 步骤(默认情况下此策略不包含此步骤)。 - 从 PDF 中提取链接可能是基本的,并且取决于超链接在文档中的嵌入方式。


> Feedback