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

核心功能
- 抓取 - 获取网页HTML内容
- 数据提取 - 使用CSS选择器提取特定元素
- 简单配置 - 易于使用的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
使用建议
- 遵守robots.txt - 在抓取前检查目标网站的robots.txt文件
- 设置合理延迟 - 避免对目标服务器造成过大压力
- 错误处理 - 生产环境中需要更完善的错误处理和重试机制
- 合法性 - 确保你的抓取行为符合法律法规和目标网站的使用条款
扩展功能建议
如需更多功能,可以考虑添加:
- 代理支持
- 用户登录/会话保持
- JavaScript渲染支持(可集成Selenium或Playwright)
- 数据清洗和格式化
- 数据库存储支持
这个精简版提供了OpenClaw的核心功能,适合学习和基础使用,对于更复杂的需求,建议使用成熟的爬虫框架如Scrapy。
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。