OpenClaw 精简版 网页数据提取工具

openclaw openclaw中文博客 2

OpenClaw 精简版是一个简单的网页数据抓取工具,使用 Python 编写,适合基础网页数据提取需求。

OpenClaw 精简版 网页数据提取工具-第1张图片-OpenClaw 中文版 - 真正能做事的 AI

核心功能

  1. 抓取 - 获取网页HTML内容
  2. 数据提取 - 使用CSS选择器提取特定元素
  3. 简单配置 - 易于使用的API接口

安装依赖

pip install requests beautifulsoup4

基础代码示例

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
import json
import time
class OpenClawLite:
    """OpenClaw 精简版 - 简单网页抓取工具"""
    def __init__(self, delay=1, timeout=10):
        """
        初始化抓取工具
        Args:
            delay: 请求延迟时间(秒),避免过于频繁请求
            timeout: 请求超时时间(秒)
        """
        self.delay = delay
        self.timeout = timeout
        self.session = requests.Session()
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        })
    def fetch_page(self, url, params=None):
        """
        获取网页内容
        Args:
            url: 目标URL
            params: 请求参数
        Returns:
            BeautifulSoup对象或None
        """
        try:
            time.sleep(self.delay)  # 延迟防止过快请求
            response = self.session.get(
                url, 
                params=params, 
                timeout=self.timeout
            )
            response.raise_for_status()
            # 检测编码
            if response.encoding == 'ISO-8859-1':
                response.encoding = response.apparent_encoding
            return BeautifulSoup(response.text, 'html.parser')
        except Exception as e:
            print(f"抓取页面失败 {url}: {e}")
            return None
    def extract_links(self, soup, base_url=None, selector='a'):
        """
        提取页面中所有链接
        Args:
            soup: BeautifulSoup对象
            base_url: 基础URL,用于解析相对链接
            selector: CSS选择器
        Returns:
            链接列表
        """
        if not soup:
            return []
        links = []
        for element in soup.select(selector):
            href = element.get('href')
            if href:
                # 处理相对链接
                if base_url and not href.startswith(('http://', 'https://')):
                    href = urljoin(base_url, href)
                links.append({
                    'url': href,
                    'text': element.get_text(strip=True),
                    'element': str(element)[:100]  # 只保留前100字符
                })
        return links
    def extract_data(self, soup, selectors):
        """
        使用CSS选择器提取数据
        Args:
            soup: BeautifulSoup对象
            selectors: 字典格式的选择器配置
                      {字段名: CSS选择器}
        Returns:
            提取的数据字典
        """
        if not soup:
            return {}
        data = {}
        for field, selector in selectors.items():
            elements = soup.select(selector)
            if elements:
                # 提取所有匹配元素的内容
                values = [elem.get_text(strip=True) for elem in elements]
                data[field] = values if len(values) > 1 else values[0]
            else:
                data[field] = None
        return data
    def scrape_pages(self, urls, selectors=None, max_pages=10):
        """
        批量抓取多个页面
        Args:
            urls: URL列表或起始URL
            selectors: 数据提取选择器(可选)
            max_pages: 最大抓取页面数
        Returns:
            抓取结果列表
        """
        results = []
        # 如果传入单个URL,转换为列表
        if isinstance(urls, str):
            urls = [urls]
        for i, url in enumerate(urls[:max_pages]):
            print(f"正在抓取 {i+1}/{min(len(urls), max_pages)}: {url}")
            soup = self.fetch_page(url)
            if not soup:
                continue
            result = {'url': url}
            # 如果提供了选择器,提取结构化数据
            if selectors:
                result['data'] = self.extract_data(soup, selectors)
            # 总是提取链接
            result['links'] = self.extract_links(soup, url)
            results.append(result)
        return results
# 使用示例
if __name__ == "__main__":
    # 创建抓取器实例
    claw = OpenClawLite(delay=2)  # 2秒延迟
    # 示例1: 提取网页所有链接
    print("=== 示例1: 提取网页链接 ===")
    soup = claw.fetch_page("https://httpbin.org/html")
    links = claw.extract_links(soup, "https://httpbin.org/html")
    print(f"找到 {len(links)} 个链接")
    for link in links[:3]:  # 只显示前3个
        print(f"  - {link['text']}: {link['url']}")
    # 示例2: 提取结构化数据
    print("\n=== 示例2: 提取结构化数据 ===")
    # 定义要提取的数据选择器
    news_selectors = {
        'title': 'h1',          # 提取所有h1标签
        'paragraphs': 'p',      # 提取所有段落
        'headings': 'h1, h2, h3'  # 提取所有标题
    }
    # 抓取页面并提取数据
    soup = claw.fetch_page("https://httpbin.org/html")
    data = claw.extract_data(soup, news_selectors)
    print("提取的数据:")
    for key, value in data.items():
        if isinstance(value, list):
            print(f"  {key}: {len(value)} 条")
            if value and isinstance(value[0], str):
                print(f"    示例: {value[0][:50]}...")
        else:
            print(f"  {key}: {value}")
    # 示例3: 批量抓取
    print("\n=== 示例3: 批量抓取多个页面 ===")
    # 定义要抓取的URL列表
    test_urls = [
        "https://httpbin.org/html",
        "https://httpbin.org/xml"
    ]
    # 批量抓取
    results = claw.scrape_pages(test_urls, max_pages=2)
    print(f"成功抓取 {len(results)} 个页面")
    # 保存结果到JSON文件
    with open('scraped_data.json', 'w', encoding='utf-8') as f:
        json.dump(results, f, ensure_ascii=False, indent=2)
    print("结果已保存到 scraped_data.json")

高级用法示例

# 定制化抓取任务
def custom_scraper():
    claw = OpenClawLite(delay=1)
    # 配置抓取规则
    config = {
        'base_url': 'https://example.com',
        'start_paths': ['/news', '/articles'],
        'selectors': {
            'article_title': '.article h1',
            'article_content': '.article .content',
            'publish_date': '.article .date',
            'author': '.article .author'
        },
        'max_depth': 2,
        'max_pages': 50
    }
    # 实现递归抓取逻辑
    def crawl_recursive(url, depth=0, visited=None):
        if visited is None:
            visited = set()
        if depth > config['max_depth'] or len(visited) >= config['max_pages']:
            return []
        if url in visited:
            return []
        visited.add(url)
        print(f"抓取深度 {depth}: {url}")
        soup = claw.fetch_page(url)
        if not soup:
            return []
        # 提取数据
        page_data = claw.extract_data(soup, config['selectors'])
        page_data['url'] = url
        page_data['depth'] = depth
        # 提取链接继续抓取
        all_results = [page_data]
        if depth < config['max_depth']:
            links = claw.extract_links(soup, config['base_url'])
            for link in links[:5]:  # 限制每个页面只抓取5个链接
                next_url = link['url']
                if next_url.startswith(config['base_url']):
                    all_results.extend(crawl_recursive(next_url, depth+1, visited))
        return all_results
    # 开始抓取
    all_results = []
    for path in config['start_paths']:
        start_url = config['base_url'] + path
        all_results.extend(crawl_recursive(start_url))
    return all_results

使用建议

  1. 遵守robots.txt - 在抓取前检查目标网站的robots.txt文件
  2. 设置合理延迟 - 避免对目标服务器造成过大压力
  3. 错误处理 - 生产环境中需要更完善的错误处理和重试机制
  4. 合法性 - 确保你的抓取行为符合法律法规和目标网站的使用条款

扩展功能建议

如需更多功能,可以考虑添加:

  • 代理支持
  • 用户登录/会话保持
  • JavaScript渲染支持(可集成Selenium或Playwright)
  • 数据清洗和格式化
  • 数据库存储支持

这个精简版提供了OpenClaw的核心功能,适合学习和基础使用,对于更复杂的需求,建议使用成熟的爬虫框架如Scrapy。

抱歉,评论功能暂时关闭!