OpenClaw 网页抓取:数据采集实战

目录

    • 摘要
    • [1. 引言 - 数据采集的价值](#1. 引言 - 数据采集的价值)
      • [1.1 数据采集应用场景](#1.1 数据采集应用场景)
      • [1.2 OpenClaw 数据采集优势](#1.2 OpenClaw 数据采集优势)
      • [1.3 数据采集流程](#1.3 数据采集流程)
    • [2. 静态页面抓取](#2. 静态页面抓取)
      • [2.1 使用 web_fetch](#2.1 使用 web_fetch)
      • [2.2 web_fetch 参数](#2.2 web_fetch 参数)
      • [2.3 实战:抓取文章内容](#2.3 实战:抓取文章内容)
      • [2.4 实战:批量抓取](#2.4 实战:批量抓取)
    • [3. 动态页面抓取](#3. 动态页面抓取)
      • [3.1 使用 Browser 工具](#3.1 使用 Browser 工具)
      • [3.2 处理无限滚动](#3.2 处理无限滚动)
      • [3.3 处理分页](#3.3 处理分页)
    • [4. 实战案例一:电商商品信息抓取](#4. 实战案例一:电商商品信息抓取)
      • [4.1 场景描述](#4.1 场景描述)
      • [4.2 实现代码](#4.2 实现代码)
      • [4.3 批量抓取商品](#4.3 批量抓取商品)
    • [5. 实战案例二:新闻文章抓取](#5. 实战案例二:新闻文章抓取)
      • [5.1 场景描述](#5.1 场景描述)
      • [5.2 实现代码](#5.2 实现代码)
    • [6. 实战案例三:社交媒体数据抓取](#6. 实战案例三:社交媒体数据抓取)
      • [6.1 场景描述](#6.1 场景描述)
      • [6.2 实现代码](#6.2 实现代码)
    • [7. 反爬虫应对](#7. 反爬虫应对)
      • [7.1 常见反爬机制](#7.1 常见反爬机制)
      • [7.2 应对策略](#7.2 应对策略)
      • [7.3 检测被封](#7.3 检测被封)
    • [8. 数据清洗与存储](#8. 数据清洗与存储)
      • [8.1 数据清洗](#8.1 数据清洗)
      • [8.2 数据存储](#8.2 数据存储)
      • [8.3 数据去重](#8.3 数据去重)
    • [9. 最佳实践](#9. 最佳实践)
      • [9.1 抓取策略](#9.1 抓取策略)
      • [9.2 礼貌爬虫原则](#9.2 礼貌爬虫原则)
      • [9.3 代码模板](#9.3 代码模板)
    • [10. 总结](#10. 总结)
      • [10.1 核心要点](#10.1 核心要点)
      • [10.2 工具选择](#10.2 工具选择)
      • [10.3 下一步](#10.3 下一步)
    • 参考资料

摘要

本文通过实际案例演示 OpenClaw 的网页数据抓取能力。从静态页面抓取、动态内容处理到大规模数据采集,全面解析数据采集的实现技巧。涵盖反爬虫应对、数据清洗、存储导出等关键环节,帮助开发者构建高效可靠的数据采集解决方案。📊


1. 引言 - 数据采集的价值

1.1 数据采集应用场景

场景 说明 数据类型
价格监控 电商价格对比 商品价格、库存
舆情分析 社交媒体监控 评论、帖子
竞品分析 竞争对手研究 产品信息、策略
内容聚合 信息整合平台 文章、新闻
研究分析 学术研究数据 论文、报告

1.2 OpenClaw 数据采集优势

OpenClaw
描述需求
AI自动抓取
智能解析
自动存储
传统爬虫
编写代码
处理反爬
解析数据
存储数据

1.3 数据采集流程

步骤 说明 工具
访问页面 打开目标网页 browser
获取内容 抓取页面数据 snapshot/web_fetch
解析数据 提取结构化信息 AI解析
存储数据 保存到文件/数据库 write

2. 静态页面抓取

2.1 使用 web_fetch

python 复制代码
# 简单的网页内容获取
result = web_fetch(
    url="https://example.com/article",
    extractMode="markdown"  # 或 "text"
)

2.2 web_fetch 参数

参数 类型 说明
url string 目标URL
extractMode string 提取模式:markdown/text
maxChars number 最大字符数

2.3 实战:抓取文章内容

python 复制代码
def fetch_article(url):
    """抓取文章内容"""
    # 获取网页内容
    content = web_fetch(
        url=url,
        extractMode="markdown",
        maxChars=10000
    )
    
    # AI 自动解析
    # 返回的是结构化的 markdown 内容
    return content

2.4 实战:批量抓取

python 复制代码
def batch_fetch(urls):
    """批量抓取多个页面"""
    results = []
    
    for url in urls:
        try:
            content = web_fetch(
                url=url,
                extractMode="markdown"
            )
            results.append({
                "url": url,
                "content": content,
                "status": "success"
            })
        except Exception as e:
            results.append({
                "url": url,
                "error": str(e),
                "status": "failed"
            })
        
        # 礼貌延迟,避免被封
        time.sleep(1)
    
    return results

3. 动态页面抓取

3.1 使用 Browser 工具

动态页面需要使用 Browser 工具,因为它可以执行 JavaScript。

python 复制代码
def fetch_dynamic_page(url):
    """抓取动态页面"""
    # 1. 打开页面
    browser(action="open", targetUrl=url)
    
    # 2. 等待动态内容加载
    browser(action="act", kind="wait", timeMs=3000)
    
    # 3. 获取快照
    snapshot = browser(action="snapshot")
    
    # 4. 从快照中提取数据
    data = extract_data_from_snapshot(snapshot)
    
    return data

3.2 处理无限滚动

python 复制代码
def fetch_infinite_scroll(url, max_scrolls=10):
    """处理无限滚动页面"""
    browser(action="open", targetUrl=url)
    
    all_data = []
    previous_count = 0
    
    for i in range(max_scrolls):
        # 获取当前数据
        snapshot = browser(action="snapshot")
        current_data = extract_items(snapshot)
        all_data.extend(current_data)
        
        # 检查是否有新数据
        if len(current_data) == previous_count:
            break
        previous_count = len(current_data)
        
        # 滚动加载更多
        browser(action="act", kind="scroll", y=1000)
        browser(action="act", kind="wait", timeMs=2000)
    
    # 去重
    unique_data = deduplicate(all_data)
    return unique_data

3.3 处理分页

python 复制代码
def fetch_paginated(base_url, max_pages=10):
    """处理分页数据"""
    all_data = []
    
    for page in range(1, max_pages + 1):
        url = f"{base_url}?page={page}"
        
        browser(action="open", targetUrl=url)
        browser(action="act", kind="wait", timeMs=2000)
        
        snapshot = browser(action="snapshot")
        page_data = extract_items(snapshot)
        
        if not page_data:
            break
        
        all_data.extend(page_data)
    
    return all_data

4. 实战案例一:电商商品信息抓取

4.1 场景描述

从电商网站抓取商品信息,包括名称、价格、评价数等。

4.2 实现代码

python 复制代码
def scrape_product_info(url):
    """抓取商品信息"""
    # 1. 打开商品页面
    browser(action="open", targetUrl=url)
    browser(action="act", kind="wait", timeMs=3000)
    
    # 2. 获取页面快照
    snapshot = browser(action="snapshot")
    
    # 3. 提取商品信息
    product = {
        "url": url,
        "name": extract_product_name(snapshot),
        "price": extract_price(snapshot),
        "rating": extract_rating(snapshot),
        "reviews": extract_review_count(snapshot),
        "stock": extract_stock_status(snapshot),
        "images": extract_image_urls(snapshot)
    }
    
    return product

def extract_product_name(snapshot):
    """提取商品名称"""
    # 查找标题元素
    for element in snapshot["elements"]:
        if element.get("type") == "heading" and element.get("level") == 1:
            return element.get("text", "")
    return ""

def extract_price(snapshot):
    """提取价格"""
    # 查找价格元素(通常包含 ¥ 或 $ 符号)
    for element in snapshot["elements"]:
        text = element.get("text", "")
        if "¥" in text or "$" in text:
            # 清理价格文本
            price = re.sub(r"[^\d.]", "", text)
            return float(price) if price else None
    return None

4.3 批量抓取商品

python 复制代码
def scrape_multiple_products(urls):
    """批量抓取多个商品"""
    products = []
    
    for url in urls:
        try:
            product = scrape_product_info(url)
            products.append(product)
            print(f"成功: {product['name']}")
        except Exception as e:
            print(f"失败: {url} - {e}")
        
        # 随机延迟,避免被封
        time.sleep(random.uniform(1, 3))
    
    # 保存结果
    save_to_json(products, "products.json")
    return products

5. 实战案例二:新闻文章抓取

5.1 场景描述

从新闻网站抓取文章列表和内容。

5.2 实现代码

python 复制代码
def scrape_news_site(base_url):
    """抓取新闻网站"""
    # 1. 打开新闻列表页
    browser(action="open", targetUrl=base_url)
    browser(action="act", kind="wait", timeMs=2000)
    
    # 2. 获取文章列表
    snapshot = browser(action="snapshot")
    article_links = extract_article_links(snapshot)
    
    # 3. 抓取每篇文章
    articles = []
    for link in article_links[:10]:  # 限制数量
        article = scrape_article(link)
        articles.append(article)
        time.sleep(1)
    
    return articles

def extract_article_links(snapshot):
    """提取文章链接"""
    links = []
    for element in snapshot["elements"]:
        if element.get("type") == "link":
            href = element.get("href", "")
            if is_article_link(href):
                links.append(href)
    return links

def scrape_article(url):
    """抓取单篇文章"""
    # 使用 web_fetch 更高效
    content = web_fetch(url=url, extractMode="markdown")
    
    # AI 自动解析标题、正文、作者等
    return {
        "url": url,
        "content": content,
        "scraped_at": datetime.now().isoformat()
    }

6. 实战案例三:社交媒体数据抓取

6.1 场景描述

从社交媒体抓取用户帖子或评论。

6.2 实现代码

python 复制代码
def scrape_social_media(url):
    """抓取社交媒体数据"""
    # 1. 打开页面
    browser(action="open", targetUrl=url)
    browser(action="act", kind="wait", timeMs=3000)
    
    # 2. 滚动加载更多内容
    for _ in range(5):
        browser(action="act", kind="scroll", y=500)
        browser(action="act", kind="wait", timeMs=1000)
    
    # 3. 获取快照
    snapshot = browser(action="snapshot")
    
    # 4. 提取帖子/评论
    posts = []
    for element in snapshot["elements"]:
        if is_post_element(element):
            posts.append({
                "author": extract_author(element),
                "content": extract_content(element),
                "time": extract_time(element),
                "likes": extract_likes(element)
            })
    
    return posts

7. 反爬虫应对

7.1 常见反爬机制

机制 说明 应对策略
User-Agent检测 检测浏览器标识 设置真实UA
请求频率限制 限制请求速度 随机延迟
IP封禁 封禁异常IP 代理IP池
验证码 人机验证 OCR/人工
动态内容 JS渲染 使用Browser

7.2 应对策略

python 复制代码
def safe_scrape(url):
    """安全的抓取策略"""
    # 1. 随机延迟
    time.sleep(random.uniform(2, 5))
    
    # 2. 模拟人类行为
    browser(action="open", targetUrl=url)
    
    # 随机滚动
    browser(action="act", kind="scroll", y=random.randint(100, 300))
    browser(action="act", kind="wait", timeMs=random.randint(1000, 3000))
    
    # 3. 获取数据
    snapshot = browser(action="snapshot")
    
    return snapshot

7.3 检测被封

python 复制代码
def check_blocked(snapshot):
    """检测是否被封"""
    # 检查是否有验证码
    if find_element(snapshot, "image", "验证码"):
        return "captcha"
    
    # 检查是否有错误提示
    if find_element(snapshot, "text", "访问频繁"):
        return "rate_limited"
    
    if find_element(snapshot, "text", "IP"):
        return "ip_blocked"
    
    return None

8. 数据清洗与存储

8.1 数据清洗

python 复制代码
def clean_data(raw_data):
    """清洗数据"""
    cleaned = []
    
    for item in raw_data:
        # 去除空白字符
        for key, value in item.items():
            if isinstance(value, str):
                item[key] = value.strip()
        
        # 去除HTML标签
        if "content" in item:
            item["content"] = remove_html_tags(item["content"])
        
        # 格式化日期
        if "date" in item:
            item["date"] = normalize_date(item["date"])
        
        cleaned.append(item)
    
    return cleaned

8.2 数据存储

python 复制代码
def save_to_json(data, filename):
    """保存为JSON"""
    with open(filename, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

def save_to_csv(data, filename):
    """保存为CSV"""
    if not data:
        return
    
    with open(filename, 'w', encoding='utf-8', newline='') as f:
        writer = csv.DictWriter(f, fieldnames=data[0].keys())
        writer.writeheader()
        writer.writerows(data)

def save_to_excel(data, filename):
    """保存为Excel"""
    import pandas as pd
    df = pd.DataFrame(data)
    df.to_excel(filename, index=False)

8.3 数据去重

python 复制代码
def deduplicate(data, key_field="url"):
    """数据去重"""
    seen = set()
    unique = []
    
    for item in data:
        key = item.get(key_field)
        if key and key not in seen:
            seen.add(key)
            unique.append(item)
    
    return unique

9. 最佳实践

9.1 抓取策略

策略 说明
先小后大 先测试少量数据
增量抓取 只抓取新数据
错误重试 失败后重试
断点续传 记录进度

9.2 礼貌爬虫原则

原则 说明
遵守robots.txt 尊重网站规则
控制频率 不给服务器压力
标识身份 设置联系信息
合理时间 避开高峰期

9.3 代码模板

python 复制代码
def polite_scrape(url):
    """礼貌的抓取"""
    # 1. 检查 robots.txt
    if not is_allowed_by_robots(url):
        raise Exception("robots.txt 禁止抓取")
    
    # 2. 随机延迟
    time.sleep(random.uniform(1, 3))
    
    # 3. 抓取数据
    try:
        data = web_fetch(url=url)
        return data
    except Exception as e:
        print(f"抓取失败: {e}")
        return None

10. 总结

10.1 核心要点

要点 说明
选择工具 静态用web_fetch,动态用browser
控制频率 避免被封禁
数据清洗 确保数据质量
合规抓取 遵守网站规则

10.2 工具选择

场景 推荐工具
静态页面 web_fetch
动态页面 browser
大量数据 browser + 增量抓取
需要登录 browser + chrome扩展

10.3 下一步

  • 第51篇:OpenClaw Canvas:可视化界面入门
  • 第52篇:OpenClaw Canvas 导航:URL 加载与控制

参考资料

相关推荐
最土老杨8 小时前
StoreClaw 电商数据智能采集与应用实战
openclaw·小龙虾·电商龙虾
无心水9 小时前
【Harness:全局认知】3、Harness 如何改写软件交付规则?从 52.8% 到 66.5% 的跨越背后
人工智能·性能优化·openclaw·养龙虾·harness·hermes·honcho
a7520662811 小时前
飞书机器人+OpenClaw(小龙虾)本地AI:从创建应用到配置AppID/Secret全流程
人工智能·机器人·飞书·openclaw·小龙虾 ai·本地 ai 智能体
鲁邦通物联网1 天前
工业储能系统应对高湿高热环境的硬件级宽温架构与Python水冷监控实战
边缘计算·数据采集·工业数据采集·边缘计算网关·5g数采
porschev1 天前
这 3 年做教育相关项目,我把一些经验整理成了一个开源 Agent Skills 项目
ai教育·openclaw·hermes agent skills
梦想画家1 天前
企业级 OpenClaw 实战:多用户身份映射与权限隔离架构指南
架构·智能体·openclaw
远创智控研发中心011 天前
基于以太网转换器的工业交换机接入方案提升数据传输效率与稳定性
数据采集·触摸屏·西门子plc·以太网模块·工业自动化
linmoo19861 天前
Agent应用实践之四 - 基础:AgentScope-SpringBoot集成源码解析
人工智能·spring boot·agent·agentscope·openclaw
前端白袍1 天前
AI+:OpenClaw:开源 AI Agent 框架的定位与技术分析
人工智能·开源·openclaw