自适应网页爬取

介绍

传统的网络爬虫遵循预先设定的模式,盲目地抓取网页,并不知道何时已经收集到足够的信息。自适应爬虫通过在爬取过程中引入智能,改变了这种模式。

把它想象成研究:当你寻找信息时,你不会把图书馆里的每一本书都读完。当你找到足够的信息来回答你的问题时,你就会停下来。这正是自适应爬虫在网页抓取中所做的事情。

关键概念

它解决的问题

在抓取网站特定信息时,您会面临两个挑战:1. 抓取不足:过早停止并丢失关键信息 2. 抓取过度:抓取不相关的页面而浪费资源

自适应爬行通过使用三层评分系统来解决这两个问题,该系统确定何时拥有“足够”的信息。

工作原理

AdaptiveCrawler 使用三个指标来衡量信息充分性:

  • 覆盖率:您收集的页面对查询词的覆盖程度
  • 一致性:跨页面信息是否一致
  • 饱和度:检测新页面何时未添加新信息

当这些指标表明已收集到足够的信息时,爬网就会自动停止。

快速入门

基本用法

from crawl4ai import AsyncWebCrawler, AdaptiveCrawler

async def main():
    async with AsyncWebCrawler() as crawler:
        # Create an adaptive crawler (config is optional)
        adaptive = AdaptiveCrawler(crawler)

        # Start crawling with a query
        result = await adaptive.digest(
            start_url="https://docs.python.org/3/",
            query="async context managers"
        )

        # View statistics
        adaptive.print_stats()

        # Get the most relevant content
        relevant_pages = adaptive.get_relevant_content(top_k=5)
        for page in relevant_pages:
            print(f"- {page['url']} (score: {page['score']:.2f})")

配置选项

from crawl4ai import AdaptiveConfig

config = AdaptiveConfig(
    confidence_threshold=0.8,    # Stop when 80% confident (default: 0.7)
    max_pages=30,               # Maximum pages to crawl (default: 20)
    top_k_links=5,              # Links to follow per page (default: 3)
    min_gain_threshold=0.05     # Minimum expected gain to continue (default: 0.1)
)

adaptive = AdaptiveCrawler(crawler, config)

爬行策略

自适应爬网支持两种不同的策略来确定信息充分性:

统计策略(默认)

统计策略采用纯信息理论和基于术语的分析:

  • 快速高效 - 无需 API 调用或模型加载
  • 基于术语的覆盖率——分析查询术语的存在和分布
  • 无外部依赖 - 离线工作
  • 最适合:具有特定术语的定义明确的查询
# Default configuration uses statistical strategy
config = AdaptiveConfig(
    strategy="statistical",  # This is the default
    confidence_threshold=0.8
)

嵌入策略

嵌入策略使用语义嵌入来获得更深入的理解:

  • 语义理解——捕捉超越精确术语匹配的含义
  • 查询扩展 - 自动生成查询变体
  • 差距驱动选择——识别知识中的语义差距
  • 基于验证的停止 - 使用保留查询来验证覆盖率
  • 最适合:复杂查询、模糊主题、概念理解
# Configure embedding strategy
config = AdaptiveConfig(
    strategy="embedding",
    embedding_model="sentence-transformers/all-MiniLM-L6-v2",  # Default
    n_query_variations=10,  # Generate 10 query variations
    embedding_min_confidence_threshold=0.1  # Stop if completely irrelevant
)

# With custom embedding provider (e.g., OpenAI)
config = AdaptiveConfig(
    strategy="embedding",
    embedding_llm_config={
        'provider': 'openai/text-embedding-3-small',
        'api_token': 'your-api-key'
    }
)

策略比较

特征 统计 嵌入
速度 非常快 中等(API 调用)
成本 自由的 取决于提供商
准确性 适用于精确术语 非常适合概念
依赖项 没有任何 嵌入模型/API
查询理解 文字 语义
最佳用例 技术文档、具体术语 研究,广泛的主题

嵌入策略配置

嵌入策略通过几个参数提供微调控制:

config = AdaptiveConfig(
    strategy="embedding",

    # Model configuration
    embedding_model="sentence-transformers/all-MiniLM-L6-v2",
    embedding_llm_config=None,  # Use for API-based embeddings

    # Query expansion
    n_query_variations=10,  # Number of query variations to generate

    # Coverage parameters
    embedding_coverage_radius=0.2,  # Distance threshold for coverage
    embedding_k_exp=3.0,  # Exponential decay factor (higher = stricter)

    # Stopping criteria
    embedding_min_relative_improvement=0.1,  # Min improvement to continue
    embedding_validation_min_score=0.3,  # Min validation score
    embedding_min_confidence_threshold=0.1,  # Below this = irrelevant

    # Link selection
    embedding_overlap_threshold=0.85,  # Similarity for deduplication

    # Display confidence mapping
    embedding_quality_min_confidence=0.7,  # Min displayed confidence
    embedding_quality_max_confidence=0.95  # Max displayed confidence
)

处理不相关的查询

嵌入策略可以检测查询何时与内容完全不相关:

# This will stop quickly with low confidence
result = await adaptive.digest(
    start_url="https://docs.python.org/3/",
    query="how to cook pasta"  # Irrelevant to Python docs
)

# Check if query was irrelevant
if result.metrics.get('is_irrelevant', False):
    print("Query is unrelated to the content!")

何时使用自适应爬行

适合:

  • 研究任务:查找有关某个主题的全面信息
  • 问答:收集足够的上下文来回答特定问题
  • 知识库构建:为 AI/ML 应用创建专用数据集
  • 竞争情报:收集有关特定产品/功能的完整信息
  • 完整站点存档:当您需要每个页面,无论其内容如何时
  • 结构化数据提取:针对特定的已知页面模式
  • 实时监控:当您需要持续更新时

理解输出

置信度分数

置信度得分(0-1)表示收集到的信息的充分性: - 0.0-0.3:信息不足,需要进一步抓取 - 0.3-0.6:信息部分,可以回答基本查询 - 0.6-0.7:覆盖范围良好,可以回答大多数查询 - 0.7-1.0:覆盖范围极佳,信息全面

统计显示

adaptive.print_stats(detailed=False)  # Summary table
adaptive.print_stats(detailed=True)   # Detailed metrics

摘要显示:- 已抓取页面与获得的置信度 - 覆盖率、一致性和饱和度分数 - 抓取效率指标

持久性和恢复

保存进度

config = AdaptiveConfig(
    save_state=True,
    state_path="my_crawl_state.json"
)

# Crawl will auto-save progress
result = await adaptive.digest(start_url, query)

恢复爬网

# Resume from saved state
result = await adaptive.digest(
    start_url,
    query,
    resume_from="my_crawl_state.json"
)

导出知识库

# Export collected pages to JSONL
adaptive.export_knowledge_base("knowledge_base.jsonl")

# Import into another session
new_adaptive = AdaptiveCrawler(crawler)
new_adaptive.import_knowledge_base("knowledge_base.jsonl")

最佳实践

1. 查询公式

  • 使用具体的描述性查询
  • 包括你希望找到的关键词
  • 避免过于宽泛的查询

2. 阈值调整

  • 从默认值(0.7)开始,供一般使用
  • 探索性爬行时降低至 0.5-0.6
  • 提高至 0.8+ 以实现全面覆盖

3.性能优化

  • 使用适当的max_pages限制
  • 调整top_k_links基于站点结构
  • 启用重复抓取的缓存
  • 爬虫根据以下原则确定链接的优先级:
  • 与查询的相关性
  • 预期信息增益
  • URL 结构和深度

示例

研究助理

# Gather information about a programming concept
result = await adaptive.digest(
    start_url="https://realpython.com",
    query="python decorators implementation patterns"
)

# Get the most relevant excerpts
for doc in adaptive.get_relevant_content(top_k=3):
    print(f"\nFrom: {doc['url']}")
    print(f"Relevance: {doc['score']:.2%}")
    print(doc['content'][:500] + "...")

知识库构建器

# Build a focused knowledge base about machine learning
queries = [
    "supervised learning algorithms",
    "neural network architectures", 
    "model evaluation metrics"
]

for query in queries:
    await adaptive.digest(
        start_url="https://scikit-learn.org/stable/",
        query=query
    )

# Export combined knowledge base
adaptive.export_knowledge_base("ml_knowledge.jsonl")

API文档爬虫

# Intelligently crawl API documentation
config = AdaptiveConfig(
    confidence_threshold=0.85,  # Higher threshold for completeness
    max_pages=30
)

adaptive = AdaptiveCrawler(crawler, config)
result = await adaptive.digest(
    start_url="https://api.example.com/docs",
    query="authentication endpoints rate limits"
)

后续步骤

常问问题

问:这与传统爬虫有何不同?答:传统爬虫遵循固定模式(广度优先/深度优先)。自适应爬虫会根据信息增益,智能地决定跟踪哪些链接以及何时停止。

问:我可以将它用于 JavaScript 密集型网站吗?答:可以!AdaptiveCrawler 继承了 AsyncWebCrawler 的所有功能,包括 JavaScript 执行。

问:它如何处理大型网站?答:算法会自然地将抓取限制在相关的部分。使用max_pages作为安全限度。

问:我可以自定义评分算法吗?答:高级用户可以实施自定义策略。请参阅自适应策略


> Feedback