OpenClaw 实战指南:从零开始构建你的第一个抓取工具
1. 引言
OpenClaw 是一个轻量级、高性能的网页抓取框架,专为需要快速构建稳定爬虫的开发者设计。它基于 Python 异步编程模型,内置了请求重试、代理轮换、数据解析和结果导出等常用功能,让你能专注于业务逻辑而非底层细节。
本文将带你从环境搭建开始,逐步深入到实际抓取案例,通过完整的代码实操,让你快速掌握 OpenClaw 的核心用法。
2. 环境准备与安装
2.1 系统要求
- Python 3.8 及以上版本
- 支持 Windows、macOS、Linux
2.2 安装 OpenClaw
推荐使用 pip 在虚拟环境中安装:
# 创建虚拟环境(可选但推荐)
python -m venv openclaw_env
source openclaw_env/bin/activate # Linux/macOS
# openclaw_env\Scripts\activate # Windows
# 安装 OpenClaw
pip install openclaw
验证安装是否成功:
import openclaw
print(openclaw.__version__)
# 预期输出类似:0.2.1
3. 第一个抓取任务:抓取静态页面
我们从最简单的场景开始——抓取一个静态 HTML 页面并提取标题和所有链接。
3.1 创建爬虫脚本
新建文件 first_spider.py:
import asyncio
from openclaw import Spider, Request, Item
class MyFirstSpider(Spider):
name = "first_spider"
# 起始 URL 列表
start_urls = ["https://example.com"]
async def parse(self, response):
"""解析响应,提取数据"""
# 提取页面标题
title = response.css("title::text").get()
# 提取所有链接
links = response.css("a::attr(href)").getall()
# 返回一个 Item 对象
yield Item({
"title": title,
"url": response.url,
"links": links,
})
# 运行爬虫
if __name__ == "__main__":
spider = MyFirstSpider()
asyncio.run(spider.run())
3.2 运行并查看结果
python first_spider.py
运行后,你会在终端看到类似输出:
[2026-07-19 16:00:00] INFO: Spider 'first_spider' started
[2026-07-19 16:00:01] INFO: Crawled (200) https://example.com
[2026-07-19 16:00:01] INFO: Item scraped: {'title': 'Example Domain', 'url': 'https://example.com', 'links': ['https://www.iana.org/domains/example']}
[2026-07-19 16:00:01] INFO: Spider 'first_spider' finished
默认情况下,抓取到的 Item 会以 JSON 格式输出到控制台。你也可以配置导出到文件。
4. 核心概念详解
4.1 Spider(爬虫)
Spider 是核心类,你需要继承它并定义:
name:爬虫的唯一标识start_urls:起始抓取地址parse方法:处理响应的回调函数
4.2 Request(请求)
Request 对象封装了一次 HTTP 请求的所有参数:
from openclaw import Request
# 基本用法
req = Request(url="https://example.com/page/2", callback=self.parse_page)
# 带参数的请求
req = Request(
url="https://api.example.com/data",
method="POST",
headers={"Authorization": "Bearer your_token"},
body='{"key": "value"}',
callback=self.parse_api
)
4.3 Item(数据项)
Item 是结构化数据的容器,通常用字典形式创建:
from openclaw import Item
# 简单 Item
item = Item({"name": "Alice", "age": 30})
# 嵌套 Item
item = Item({
"product": {
"name": "Laptop",
"price": 999.99,
"specs": ["16GB RAM", "512GB SSD"]
}
})
4.4 Response(响应)
Response 对象提供了多种数据提取方式:
# CSS 选择器
response.css("div.content p::text").get()
response.css("div.item").getall()
# XPath 选择器
response.xpath("//div[@class='content']/p/text()").get()
response.xpath("//a/@href").getall()
# 正则表达式
response.re(r"价格:(\d+\.\d{2})")
response.re_first(r"订单号:([A-Z0-9]+)")
5. 实战案例:抓取电商商品列表
现在我们来做一个更贴近实际的案例——抓取一个模拟电商网站的商品列表,并处理分页。
5.1 目标分析
假设我们要抓取 https://books.toscrape.com/(一个专门用于练习爬虫的图书网站),需要提取:
- 每本书的标题、价格、库存状态
- 翻页抓取所有商品
5.2 完整代码
创建 book_spider.py:
import asyncio
from openclaw import Spider, Request, Item
class BookSpider(Spider):
name = "book_spider"
start_urls = ["https://books.toscrape.com/"]
async def parse(self, response):
"""解析列表页"""
books = response.css("article.product_pod")
for book in books:
# 提取单本书信息
title = book.css("h3 a::attr(title)").get()
price = book.css("p.price_color::text").get()
stock = book.css("p.instock.availability::text").get()
# 获取详情页链接
detail_url = book.css("h3 a::attr(href)").get()
if detail_url:
# 拼接完整 URL
full_url = response.urljoin(detail_url)
# 发起详情页请求,并传递已提取的数据
yield Request(
url=full_url,
callback=self.parse_detail,
meta={"title": title, "price": price, "stock": stock}
)
# 处理分页
next_page = response.css("li.next a::attr(href)").get()
if next_page:
next_url = response.urljoin(next_page)
yield Request(url=next_url, callback=self.parse)
async def parse_detail(self, response):
"""解析详情页,提取更多信息"""
# 从 meta 中获取列表页已提取的数据
title = response.meta["title"]
price = response.meta["price"]
stock = response.meta["stock"]
# 提取详情页特有的数据
description = response.css("meta[name='description']::attr(content)").get()
upc = response.xpath("//th[text()='UPC']/following-sibling::td/text()").get()
yield Item({
"title": title,
"price": price,
"stock": stock.strip() if stock else None,
"description": description.strip() if description else None,
"upc": upc,
"detail_url": response.url,
})
if __name__ == "__main__":
spider = BookSpider()
asyncio.run(spider.run())
5.3 运行与结果导出
# 运行爬虫,并将结果保存到 JSON 文件
python book_spider.py -o books.json
查看 books.json 文件,你会看到类似这样的结构化数据:
[
{
"title": "A Light in the Attic",
"price": "£51.77",
"stock": "In stock",
"description": "It's hard to imagine a world without A Light in the Attic.",
"upc": "a897fe39b8b0c8b9",
"detail_url": "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html"
},
...
]
6. 高级功能
6.1 配置中间件
OpenClaw 支持通过中间件实现请求重试、代理轮换、User-Agent 随机化等功能:
# config.py
from openclaw import Settings
settings = Settings()
settings.set("DOWNLOAD_DELAY", 1.5) # 请求间隔 1.5 秒
settings.set("RETRY_TIMES", 3) # 失败重试 3 次
settings.set("CONCURRENT_REQUESTS", 8) # 并发请求数
settings.set("USER_AGENT", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
settings.set("PROXY_ENABLED", True)
settings.set("PROXY_LIST", [
"http://proxy1.example.com:8080",
"http://proxy2.example.com:8080",
])
在爬虫中加载配置:
class MySpider(Spider):
name = "my_spider"
custom_settings = {
"DOWNLOAD_DELAY": 2.0,
"CONCURRENT_REQUESTS": 4,
}
# ...
6.2 数据管道(Pipeline)
Pipeline 用于对抓取到的 Item 进行后处理,如清洗、去重、存储到数据库:
# pipelines.py
import json
class JsonPipeline:
"""将 Item 写入 JSON 文件"""
def __init__(self):
self.items = []
async def process_item(self, item):
self.items.append(dict(item))
return item
async def close_spider(self):
with open("output.json", "w", encoding="utf-8") as f:
json.dump(self.items, f, ensure_ascii=False, indent=2)
class DuplicatesPipeline:
"""去重 Pipeline"""
def __init__(self):
self.seen = set()
async def process_item(self, item):
if item["title"] in self.seen:
raise DropItem(f"Duplicate item: {item['title']}")
self.seen.add(item["title"])
return item
在爬虫中启用 Pipeline:
class MySpider(Spider):
name = "my_spider"
pipelines = [JsonPipeline(), DuplicatesPipeline()]
# ...
6.3 处理 JavaScript 渲染页面
对于动态加载的页面,OpenClaw 支持集成 Playwright:
from openclaw import Spider, Request
from openclaw.downloader import PlaywrightDownloader
class JsSpider(Spider):
name = "js_spider"
downloader = PlaywrightDownloader() # 使用 Playwright 下载器
async def parse(self, response):
# 此时 response 已经是 JavaScript 渲染后的完整 HTML
title = response.css("h1::text").get()
yield Item({"title": title})
7. 常见问题与调试技巧
7.1 请求被屏蔽
- 降低请求频率:设置
DOWNLOAD_DELAY - 随机化 User-Agent:使用中间件随机切换
- 使用代理 IP:配置
PROXY_LIST - 添加 Cookie:在
Request中传入cookies参数
7.2 调试日志
import logging
logging.basicConfig(level=logging.DEBUG) # 开启 DEBUG 日志
7.3 断点续爬
OpenClaw 支持请求队列持久化,中断后可以继续:
spider = MySpider()
spider.run(job_dir="./crawl_jobs") # 指定作业目录,支持断点续爬
8. 总结
本文从零开始,通过多个实操案例详细介绍了 OpenClaw 的使用方法:
- 环境搭建:安装与验证
- 基础用法:抓取静态页面,提取数据
- 核心概念:Spider、Request、Item、Response
- 实战案例:电商商品列表抓取,含分页处理
- 高级功能:中间件、Pipeline、JS 渲染
- 调试技巧:反爬应对、日志、断点续爬
OpenClaw 的设计哲学是「简单但不简陋」,它提供了足够丰富的功能来应对大多数抓取场景,同时保持了代码的简洁和可读性。建议你从本文的示例开始,逐步修改和扩展,在实践中掌握它的精髓。
更多推荐

所有评论(0)