Crawl4AI 页面交互指南

102
0
0
2024-11-11

Crawl4AI 页面交互指南

Crawl4AI 提供了强大的功能,用于与动态网页交互,处理 JavaScript 执行和管理页面事件。

JavaScript 执行

基本执行

# 单个 JavaScript 命令

python
result = await crawler.arun(
    url="https://example.com", 
    js_code="window.scrollTo(0, document.body.scrollHeight);"
)

# 多个命令

python
js_commands = [
    "window.scrollTo(0, document.body.scrollHeight);",
    "document.querySelector('.load-more').click();",
    "document.querySelector('#consent-button').click();"
]
result = await crawler.arun(
    url="https://example.com", 
    js_code=js_commands
)

等待条件

CSS 基等待

等待元素出现:

python
result = await crawler.arun(
    url="https://example.com", 
    wait_for="css:.dynamic-content"  # 等待类名为 'dynamic-content' 的元素出现
)

JavaScript 基等待

等待自定义条件:

# 等待元素数量

python
wait_condition = """() => {
    return document.querySelectorAll('.item').length > 10;
}"""

result = await crawler.arun(
    url="https://example.com", 
    wait_for=f"js:{wait_condition}"
)

# 等待动态内容加载

python
wait_for_content = """() => {
    const content = document.querySelector('.content');
    return content && content.innerText.length > 100;
}"""

result = await crawler.arun(
    url="https://example.com", 
    wait_for=f"js:{wait_for_content}"
)

处理动态内容

加载更多内容

处理无限滚动或加载更多按钮:

# 滚动并等待模式

python
result = await crawler.arun(
    url="https://example.com", 
    js_code=[
        # 滚动到底部
        "window.scrollTo(0, document.body.scrollHeight);",
        # 如果存在则点击加载更多
        "const loadMore = document.querySelector('.load-more'); if(loadMore) loadMore.click();"
    ],
    # 等待新内容
    wait_for="js:() => document.querySelectorAll('.item').length > previousCount"
)

表单交互

处理表单和输入:

python
js_form_interaction = """
    // 填充表单字段
    document.querySelector('#search').value = 'search term';
    // 提交表单
    document.querySelector('form').submit();
"""

result = await crawler.arun(
    url="https://example.com", 
    js_code=js_form_interaction,
    wait_for="css:.results"  # 等待结果加载
)

时间控制

延迟和超时

控制交互的时间:

python
result = await crawler.arun(
    url="https://example.com", 
    page_timeout=60000,              # 页面加载超时(毫秒)
    delay_before_return_html=2.0,    # 捕获内容前等待
)

复杂交互示例

以下是一个处理具有多个交互的动态页面的示例:

python
async def crawl_dynamic_content():
    async with AsyncWebCrawler() as crawler:
        # 初始页面加载
        result = await crawler.arun(
            url="https://example.com", 
            # 处理 Cookie 同意
            js_code="document.querySelector('.cookie-accept')?.click();",
            wait_for="css:.main-content"
        )

        # 加载更多内容
        session_id = "dynamic_session"  # 保持会话以进行多次交互

        for page in range(3):  # 加载 3 页内容
            result = await crawler.arun(
                url="https://example.com", 
                session_id=session_id,
                js_code=[
                    # 滚动到底部
                    "window.scrollTo(0, document.body.scrollHeight);",
                    # 存储当前项目计数
                    "window.previousCount = document.querySelectorAll('.item').length;",
                    # 点击加载更多
                    "document.querySelector('.load-more')?.click();"
                ],
                # 等待新项目
                wait_for="""() => {
                    const currentCount = document.querySelectorAll('.item').length;
                    return currentCount > window.previousCount;
                }""",
                # 仅执行 JS 而不重新加载页面
                js_only=True if page > 0 else False
            )

            # 每次加载后处理内容
            print(f"第 {page + 1} 页项目数:", len(result.cleaned_html))

        # 清理会话
        await crawler.crawler_strategy.kill_session(session_id)

与提取策略结合使用

将页面交互与结构化提取结合起来:

python
from crawl4ai.extraction_strategy import JsonCssExtractionStrategy, LLMExtractionStrategy

# 交互后的基于模式的提取
schema = {
    "name": "Dynamic Items",
    "baseSelector": ".item",
    "fields": [
        {"name": "title", "selector": "h2", "type": "text"},
        {"name": "description", "selector": ".desc", "type": "text"}
    ]
}

result = await crawler.arun(
    url="https://example.com", 
    js_code="window.scrollTo(0, document.body.scrollHeight);",
    wait_for="css:.item:nth-child(10)",  # 等待第 10 个项目
    extraction_strategy=JsonCssExtractionStrategy(schema)
)

# 或使用 LLM 分析动态内容
class ContentAnalysis(BaseModel):
    topics: List[str]
    summary: str

result = await crawler.arun(
    url="https://example.com", 
    js_code="document.querySelector('.show-more').click();",
    wait_for="css:.full-content",
    extraction_strategy=LLMExtractionStrategy(
        provider="ollama/nemotron",
        schema=ContentAnalysis.schema(),
        instruction="分析完整内容"
    )
)