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 加载与控制

参考资料

相关推荐
七夜zippoe17 小时前
OpenClaw Prompt 工程:从角色设定到 Skill 封装的 Agent 输出质量方法论
java·服务器·prompt·openclaw·skill封装
远创智控研发中心012 天前
小型电动船舶岸边检测,开关量无线传输模块实现码头无线信号采集
数据采集·无线通讯·工业自动化·无线数传模块·无线网桥·开关量转无线
AC赳赳老秦2 天前
CSDN 技术社区数据采集:OpenClaw 抓取公开技术热帖,生成领域技术热点周报
java·大数据·前端·数据库·python·php·openclaw
console.log('npc')2 天前
OpenClaw 使用教程:开源 AI Agent 编排框架完全指南
人工智能·microsoft·ai编程·openclaw
栈溢出的浪漫2 天前
技术速递|基于 OpenClaw、MCP 和 Azure Container Apps 构建自主 Microsoft Teams 智能体
mcp·openclaw·自主智能体·技术速递·azurecontainerapps
qq_349447952 天前
Windows系统安装openclaw(源码安装)
openclaw
捷米特网关模块通讯2 天前
工厂能源管控平台搭建,捷米特 JM-RS-WIFI 实现多台空压机、冷水机组集中监测、故障预警案例
无线通信·数据采集·工业自动化·无线数传模块·无线网桥
AC赳赳老秦3 天前
GitHub 开源项目数据采集:OpenClaw 抓取星标与贡献者数据,深度分析技术发展趋势
大数据·前端·数据库·python·开源·github·openclaw
超级小的大杯柠檬水4 天前
绿联云 NAS 安装 OpenClaw 简明指南
openclaw
AC赳赳老秦4 天前
软著公开信息批量采集:OpenClaw 抓取软件著作权公开数据,分析企业技术布局方向
大数据·网络·人工智能·python·php·deepseek·openclaw