1.定义数据结构

openclaw openclaw解答 1

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

1.定义数据结构-第1张图片-官方openclaw下载|openclaw官网-国内ai小龙虾下载

核心特性

  1. 完全异步:基于 asyncioaiohttp,能轻松管理数千个并发请求。
  2. 结构化:提供 ItemPipelineDownloader MiddlewareSpider Middleware 等组件,代码组织清晰。
  3. 灵活调度:内置优先级队列调度器,可自定义请求去重规则。
  4. 中间件支持:通过中间件可方便地处理代理、请求头、Cookies、响应预处理等。
  5. 易于扩展:可以轻松编写自定义的 Pipeline 来处理数据,或 Middleware 来修改请求/响应。
  6. 支持动态渲染:可集成 playwrightselenium 处理 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选择器,返回SelectorList
    • response.xpath('xpath'): 使用XPath
    • response.json(): 将响应文本解析为JSON
    • response.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 方法:默认的请求回调函数,它可以 yield Item 或新的 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)
    # ... 其他参数
)

高级技巧与最佳实践

  1. 错误处理:在 parse 方法中使用 try...except,框架会自动重试失败的请求(根据配置)。
  2. 控制并发与速度:合理设置 concurrencydelay,避免对目标服务器造成过大压力。
  3. 数据去重:可以在 Pipeline 中实现,或者利用 Requestmeta 和自定义的去重中间件。
  4. 分布式爬虫:OpenClaw 本身不是分布式框架,对于大规模爬取,需要结合消息队列(如 RabbitMQ, Redis)和数据库,自行调度多个爬虫实例。
  5. 遵守 robots.txt:框架没有内置 robots.txt 检查器,对于公开网站,请务必尊重 robots.txt 规则,并在请求头中设置一个明确的 User-Agent

OpenClaw 提供了一个现代化、异步的爬虫框架结构,它的学习曲线比纯 aiohttp 手写代码要平缓,比 Scrapy 更轻量且原生异步。

适合场景:需要高并发、I/O 密集型的中大型爬虫项目,且你希望代码有良好的结构和可维护性。

不适合场景:极其简单的、一次性的爬取任务(用 requests + BeautifulSoup 更直接),或者需要 Scrapy 庞大生态系统(如 scrapy-redis)的复杂分布式爬虫。

建议从官方 GitHub 仓库的示例和源码开始,以获取最新和最深入的信息。

标签: 定义 数据结构

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