PDF 处理策略
Crawl4AI 提供了专门用于处理和提取 PDF 文件内容的策略。这些策略允许您将 PDF 处理无缝集成到您的爬取工作流中,无论 PDF 是托管在线上还是存储在本地。
PDFCrawlerStrategy
概述
PDFCrawlerStrategy
是 AsyncCrawlerStrategy
的一个实现,专为 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
:- 此方法由
AsyncWebCrawler
在arun
过程中调用。 - 它接收
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
概述
PDFContentScrapingStrategy
是 ContentScrapingStrategy
的一个实现,旨在从 PDF 文档中提取文本、元数据以及可选的图像。它旨在与能够为其提供 PDF 源的爬取器策略(如 PDFCrawlerStrategy
)结合使用。该策略在内部使用 NaivePDFProcessorStrategy
来执行底层 PDF 解析。
使用时机
当您的 AsyncWebCrawler
(通常配置了 PDFCrawlerStrategy
)需要以下功能时,请使用 PDFContentScrapingStrategy
:
- 从 PDF 文档中逐页提取文本内容。
- 检索 PDF 内嵌入的标准元数据(例如,标题、作者、主题、创建日期、页数)。
- 可选地,提取 PDF 页面中包含的图像。这些图像可以保存到本地目录或供进一步处理。
- 生成可以转换为 CrawlResult
的 ScrapingResult
,使 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_locally
为 True
,提取的图像应保存到的目录。如果为 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_images
为True
,则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://
或直接路径),它会解析并返回本地路径。
- 一个私有的辅助方法,用于管理 PDF 文件访问。如果
使用示例
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 中提取链接可能是基本的,并且取决于超链接在文档中的嵌入方式。