OpenClaw 是一个基于 Python asyncio 的异步网络爬虫框架,设计目标是简单、灵活、高性能,它采用了类似 Scrapy 的架构思想(如 Items、Pipelines),但完全基于异步 IO,特别适合处理高并发、I/O 密集型的网页抓取任务。

核心特性
- 完全异步:基于
asyncio和aiohttp,能轻松管理数千个并发请求。 - 结构化:提供
Item、Pipeline、Downloader Middleware、Spider Middleware等组件,代码组织清晰。 - 灵活调度:内置优先级队列调度器,可自定义请求去重规则。
- 中间件支持:通过中间件可方便地处理代理、请求头、Cookies、响应预处理等。
- 易于扩展:可以轻松编写自定义的 Pipeline 来处理数据,或 Middleware 来修改请求/响应。
- 支持动态渲染:可集成
playwright或selenium处理 JavaScript 渲染的页面。
安装
pip install openclaw
如果需要动态渲染支持,还需安装:
pip install playwright playwright install # 安装浏览器驱动
快速入门:一个简单的例子
我们以爬取Quotes to Scrape为例。
import asyncio
from openclaw import OpenClaw
from openclaw.items import Item
from openclaw.http import Request
class QuoteItem(Item):
# 定义字段,会自动从 response 的 css/json 方法中提取
text: str
author: str
tags: list
# 2. 创建爬虫类
class QuotesSpider:
name = "quotes_spider"
start_urls = ["http://quotes.toscrape.com/page/1/"]
async def parse(self, response):
# 解析列表页
for quote in response.css('div.quote'):
item = QuoteItem()
# 使用 CSS 选择器提取数据,并填充到 Item
item['text'] = quote.css('span.text::text').get()
item['author'] = quote.css('small.author::text').get()
item['tags'] = quote.css('div.tags a.tag::text').getall()
# 提交 Item 到 Pipeline
yield item
# 翻页:生成新的 Request 对象,并指定回调函数
next_page = response.css('li.next a::attr(href)').get()
if next_page is not None:
next_url = response.urljoin(next_page)
yield Request(next_url, callback=self.parse)
# 3. 运行爬虫
async def main():
claw = OpenClaw(QuotesSpider())
# 可以在这里添加自定义的 Pipeline 或 Middleware
await claw.run()
if __name__ == '__main__':
asyncio.run(main())
核心概念与详细用法
Item
Item 是数据的容器,定义了你希望从网页中提取的字段。
from openclaw.items import Item, Field
class ProductItem(Item):= Field() # 也可以使用类型注解:title: str
price = Field()
description = Field(default='') # 默认值
sku = Field(alias='product_sku') # 别名,用于从JSON等数据源匹配
Request & Response
- Request:代表一个HTTP请求,可以指定
url,method,headers,cookies,callback,meta(传递额外信息)等。yield Request(url, callback=self.parse_detail, meta={'item': partial_item}) - Response:代表一个HTTP响应,提供了常用的解析方法:
response.text: 响应文本response.css('selector'): 使用CSS选择器,返回SelectorListresponse.xpath('xpath'): 使用XPathresponse.json(): 将响应文本解析为JSONresponse.urljoin(relative_url): 拼接相对URL为绝对URL
Spider (爬虫)
爬虫是定义爬取逻辑的核心类,必须包含 name 属性和 parse 方法(或自定义的回调方法)。
start_requests方法:可以覆盖此方法来定制起始请求(例如携带POST数据)。async def start_requests(self): for url in self.start_urls: yield Request(url, callback=self.parse, headers={'Custom-Header': 'value'})parse方法:默认的请求回调函数,它可以yieldItem或新的Request,形成爬取流。
Pipeline (管道)
Pipeline 用于处理 Spider 提取到的 Item,典型用途:数据清洗、验证、去重、存储。
-
启用 Pipeline:在实例化
OpenClaw时传入。 -
编写自定义 Pipeline:
import json class JsonWriterPipeline: def __init__(self): self.file = None async def open_spider(self, spider): # 爬虫启动时调用 self.file = open(f'{spider.name}_items.json', 'w', encoding='utf-8') async def close_spider(self, spider): # 爬虫关闭时调用 self.file.close() async def process_item(self, item, spider): # 对每个 Item 进行处理 line = json.dumps(dict(item), ensure_ascii=False) + "\n" self.file.write(line) return item # 必须返回 Item 或 DropItem 异常 # 使用 claw = OpenClaw(QuotesSpider(), pipelines=[JsonWriterPipeline()])框架会按顺序调用所有 Pipeline 的
process_item方法。
Middleware (中间件)
中间件可以全局处理请求和响应。
-
Downloader Middleware:在请求发送前和响应返回后起作用,常用于设置代理、更换UA、处理重试等。
from openclaw.middlewares import DownloaderMiddleware class RandomUserAgentMiddleware(DownloaderMiddleware): user_agents = ['Mozilla/5.0 ...', 'Another UA/1.0 ...'] async def process_request(self, request, spider): import random if request.headers.get('User-Agent') is None: request.headers['User-Agent'] = random.choice(self.user_agents) return None # 返回 None 表示继续处理该请求 # 使用 claw = OpenClaw(QuotesSpider(), downloader_middlewares=[RandomUserAgentMiddleware()]) -
Spider Middleware:在 Spider 接收 Response 前和处理 Item/Request 后起作用,用途相对较少。
处理动态页面 (Playwright 集成)
对于需要执行 JavaScript 的页面,可以使用 PlaywrightRequest。
from openclaw.http import PlaywrightRequest
class DynamicSpider:
name = "dynamic_spider"
async def start_requests(self):
# 使用 PlaywrightRequest
yield PlaywrightRequest(
"https://example.com/dynamic",
callback=self.parse_dynamic,
# 可选:在页面上执行脚本
script="window.scrollTo(0, document.body.scrollHeight);",
wait_for="div.loaded-content" # 可选:等待某个元素出现
)
async def parse_dynamic(self, response):
# response 包含由 Playwright 渲染后的页面 HTML
data = response.css('div.data::text').get()
yield MyItem(data=data)
注意:使用 PlaywrightRequest 会显著降低爬取速度,请仅对必要页面使用。
配置
可以在实例化 OpenClaw 时传递配置参数:
claw = OpenClaw(
spider=MySpider(),
concurrency=10, # 并发请求数
delay=1.0, # 请求间最小延迟(秒)
retries=3, # 失败重试次数
retry_delay=5.0, # 重试延迟
timeout=30, # 请求超时(秒)
use_proxy=False, # 是否使用代理(需配合相应Middleware)
# ... 其他参数
)
高级技巧与最佳实践
- 错误处理:在
parse方法中使用try...except,框架会自动重试失败的请求(根据配置)。 - 控制并发与速度:合理设置
concurrency和delay,避免对目标服务器造成过大压力。 - 数据去重:可以在 Pipeline 中实现,或者利用
Request的meta和自定义的去重中间件。 - 分布式爬虫:OpenClaw 本身不是分布式框架,对于大规模爬取,需要结合消息队列(如 RabbitMQ, Redis)和数据库,自行调度多个爬虫实例。
- 遵守 robots.txt:框架没有内置 robots.txt 检查器,对于公开网站,请务必尊重
robots.txt规则,并在请求头中设置一个明确的User-Agent。
OpenClaw 提供了一个现代化、异步的爬虫框架结构,它的学习曲线比纯 aiohttp 手写代码要平缓,比 Scrapy 更轻量且原生异步。
适合场景:需要高并发、I/O 密集型的中大型爬虫项目,且你希望代码有良好的结构和可维护性。
不适合场景:极其简单的、一次性的爬取任务(用 requests + BeautifulSoup 更直接),或者需要 Scrapy 庞大生态系统(如 scrapy-redis)的复杂分布式爬虫。
建议从官方 GitHub 仓库的示例和源码开始,以获取最新和最深入的信息。