ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基于OpenClaw与RPA的滴滴司机位置查询智能体开发实战

2026/8/15 13:36:08 拓冰建站 浏览量
基于OpenClaw与RPA的滴滴司机位置查询智能体开发实战 1. 项目概述当AI智能体遇上打车场景最近在折腾OpenClaw这个AI智能体框架发现社区里讨论得挺火。作为一个喜欢用技术解决实际问题的开发者我一直在想能不能让AI不只是聊天而是真的去“做事”。正好我每天通勤都要用打车软件等车时最焦虑的就是“司机到哪了”。虽然App里有地图但总得手动点开、刷新有时候网络不好还加载不出来。于是一个想法冒了出来能不能用OpenClaw做一个智能助手让它自动帮我查询滴滴打车的司机实时位置甚至预测到达时间然后通过我习惯的渠道比如飞书、微信主动推送给我这个项目我称之为“用OpenClaw实现滴滴打车查询司机位置”。它的核心不是再造一个打车App而是利用OpenClaw作为“大脑”和“执行者”去自动化操作现有的滴滴打车服务获取我们关心的信息。这背后涉及几个关键点首先OpenClaw需要理解我的自然语言指令比如“帮我看看我的车到哪了”其次它需要能模拟用户操作安全地登录滴滴、获取订单状态和司机位置数据最后它还得把结果清晰地呈现给我。整个过程我希望它是静默的、自动化的就像有个贴心的助理在后台默默处理一切。听起来有点像是“薅”了现有服务的羊毛但技术上这其实是对RPA机器人流程自动化和AI智能体能力的一次有趣探索。它适合谁呢我觉得有三类朋友可能会感兴趣一是像我一样喜欢折腾自动化、提升生活效率的极客二是想深入学习OpenClaw框架了解智能体如何与真实世界API或网页交互的开发者三是那些对RPA应用场景好奇想看看AI如何替代重复性手动操作的产品或运营同学。接下来我就把自己从零搭建这个项目的完整过程、踩过的坑以及一些核心思考毫无保留地分享出来。2. 核心思路与方案选型为什么是OpenClaw在决定用OpenClaw之前我其实评估过几种方案。最直接的当然是写一个Python脚本用requests库模拟请求滴滴的接口。但这条路很快被我否了原因有二一是滴滴的接口肯定有复杂的加密和风控逆向工程成本高且法律风险大二是脚本是“死”的它无法理解“我的车”这个上下文每次都需要我输入订单号不够智能。另一种方案是用传统的RPA工具比如UiPath或影刀它们擅长网页自动化。但这类工具通常比较“重”配置复杂而且和AI的自然语言理解结合得不够紧密难以实现“说人话”就能触发任务。OpenClaw吸引我的地方恰恰在于它试图融合两者。它本质上是一个智能体Agent框架核心思想是让一个大语言模型LLM作为决策中枢去调用各种工具Skill来完成复杂任务。对于我们的打车查询场景这个架构就非常贴切大脑LLM负责理解我的模糊指令比如“司机到哪了”并将其转化为明确的操作步骤检查是否有进行中的订单 - 获取订单详情 - 提取司机位置 - 组织回复。手脚SkillsOpenClaw提供了丰富的预置Skill也支持自定义。我们需要的就是一个能够与滴滴打车App或网页端进行安全交互的Skill。我的方案是利用OpenClaw的Web自动化或自定义API Skill能力模拟用户操作滴滴打车微信小程序或App安全地抓取订单状态页面信息然后通过解析页面元素或监听网络请求在合规前提下来获取司机位置数据。选择小程序/App而不是网页端是因为前者更贴近普通用户的使用场景且通常有更稳定的接口。这里有一个非常重要的原则必须强调一切自动化操作必须严格遵守目标平台的服务条款不能进行恶意爬取、刷单或干扰服务正常运行。本项目的目的是技术探索与个人效率提升所有操作应模拟真实用户的合理查询频率和交互方式。OpenClaw的playwright或selenium类Skill在设计上也是模拟真人点击这比直接攻击API要合规得多。2.1 技术栈与工具选型基于以上思路我确定了以下技术栈核心框架OpenClaw。我选择其Docker部署版本便于环境隔离和依赖管理。大模型LLM本地部署的Ollama qwen2.5:7b模型。选择Qwen是因为它在中文理解和工具调用方面表现不错7B参数规模在消费级显卡如RTX 4060上也能流畅运行。完全本地化也保证了隐私和安全。自动化工具OpenClaw的web_playwrightSkill。Playwright相比Selenium更现代对单页应用SPA支持更好且OpenClaw对其集成度更高。部署环境Ubuntu 22.04 LTS服务器使用Docker Compose编排OpenClaw和Ollama。为什么用Ubuntu和Docker因为稳定、资源可控并且社区教程丰富出了问题容易搜索到解决方案。交互通道计划接入飞书机器人作为最终通知界面。飞书的开放API完善文档清晰适合作为AI智能体的“前台”。这个技术栈的优点是全链路可控从AI决策到自动化执行再到通知都在自己的服务器上完成没有第三方数据泄露风险。难点在于需要让OpenClaw的LLM“学会”在合适的时候调用我们的滴滴查询Skill并且Skill本身要足够健壮能处理登录验证、网络延迟、页面元素变化等各种异常情况。3. 环境部署与OpenClaw配置实战理论说得再多不如动手搭起来。这一部分我会详细记录从零部署OpenClaw和Ollama的每一步特别是那些官方文档可能一笔带过但实际操作中很容易卡住的地方。3.1 基础环境与Ollama部署我的服务器是一台4核8G内存的云主机系统是干净的Ubuntu 22.04。首先更新系统并安装必要的工具sudo apt update sudo apt upgrade -y sudo apt install -y curl git docker.io docker-compose接下来部署Ollama。这里我采用Docker方式比直接下载二进制文件更便于管理。# 创建Ollama的数据目录用于保存模型 sudo mkdir -p /opt/ollama sudo chown -R $USER:$USER /opt/ollama # 使用Docker运行Ollama docker run -d \ --name ollama \ --restart always \ -p 11434:11434 \ -v /opt/ollama:/root/.ollama \ ollama/ollama # 等待服务启动后拉取Qwen2.5模型 docker exec ollama ollama pull qwen2.5:7b注意ollama pull可能会很慢因为模型有4-5个GB。建议在后台进行或者使用screen或tmux会话以防网络中断。也可以先拉取更小的模型如qwen2.5:0.5b做测试。验证Ollama是否工作curl http://localhost:11434/api/generate -d { model: qwen2.5:7b, prompt: 你好, stream: false }如果看到返回了JSON格式的回复说明Ollama部署成功。3.2 Docker部署OpenClawOpenClaw的官方仓库提供了Docker Compose示例这是最省心的方式。# 克隆官方示例仓库这里以某个社区维护的compose文件为例实际请以OpenClaw最新官方文档为准 git clone https://github.com/openclaw/openclaw-quickstart.git cd openclaw-quickstart/docker-compose编辑docker-compose.yml文件关键是要配置Ollama的地址让OpenClaw能连接到我们刚部署的模型。version: 3.8 services: openclaw: image: openclaw/openclaw:latest container_name: openclaw restart: unless-stopped ports: - 3000:3000 # OpenClaw Web UI端口 environment: - OLLAMA_BASE_URLhttp://host.docker.internal:11434 # 关键让容器内能访问宿主机的Ollama - DEFAULT_MODELqwen2.5:7b - OPENCLAW_API_KEYyour_secret_key_here # 设置一个API密钥用于安全调用 volumes: - ./data:/app/data # 持久化数据 extra_hosts: - host.docker.internal:host-gateway # 用于Docker容器访问宿主机服务这里有个大坑在Linux Docker中host.docker.internal可能无法直接解析。更可靠的办法是使用宿主机的实际IP地址或者创建一个共享网络。我采用的方法是使用network_mode: host但这会牺牲一些隔离性。对于新手我建议先使用以下变通方法修改环境变量environment: - OLLAMA_BASE_URLhttp://你服务器的内网IP:11434 # 例如 172.17.0.1保存配置后启动服务docker-compose up -d访问http://你的服务器IP:3000应该能看到OpenClaw的Web界面。首次进入可能需要输入前面设置的OPENCLAW_API_KEY。3.3 配置模型与测试基础对话在OpenClaw的Web界面中进入设置或模型管理页面。我们需要添加Ollama模型。模型类型选择Ollama。模型名称填qwen2.5:7b。基础URL填http://宿主机IP:11434与docker-compose中一致。保存并设置为默认模型。然后在聊天界面尝试发送一句“你好世界”。如果能看到来自Qwen模型的流畅回复恭喜你OpenClaw的核心AI引擎已经就绪。但此时它还是个“光杆司令”只会聊天不会打车。因为我们还没有赋予它“查询司机位置”这个能力。实操心得部署过程最常出问题的地方就是网络连通性。务必确保OpenClaw容器能ping通Ollama服务的IP和端口。可以在OpenClaw容器内执行docker exec openclaw curl http://宿主机IP:11434/api/tags来测试。如果失败检查防火墙ufw或firewalld是否放行了11434端口或者Docker网络配置是否正确。4. 核心Skill开发滴滴查询自动化这是整个项目最核心、也最具挑战性的一环。我们需要创建一个自定义Skill让OpenClaw能操作滴滴打车。考虑到合规性和复杂性我们采取一种“半自动化”的稳健策略不直接破解API而是通过自动化工具获取授权后的页面信息。4.1 技能设计思路我设计的didichuxing_skill主要包含以下功能函数get_current_order(): 检查当前是否有进行中的订单。get_driver_location(order_id): 获取指定订单的司机实时位置经纬度或地图快照。estimate_arrival_time(order_id): 估算司机到达时间。如何实现我的计划是利用Playwright自动化登录滴滴打车微信小程序因为小程序登录态更持久且界面相对稳定。技能的工作流程如下启动技能初始化时启动一个Playwright浏览器实例并打开滴滴打车小程序需要事先在桌面版微信登录。状态维持维护这个浏览器会话避免每次查询都重新登录。查询当收到查询指令时自动化脚本执行点击“我的行程” - 选择最新订单 - 进入订单详情页 - 抓取地图区域或位置文本。数据解析从页面中提取位置信息可能是文本如“司机已到达XX路”也可能是地图组件的静态截图。4.2 Skill代码结构详解在OpenClaw中自定义Skill通常是一个Python类。我在OpenClaw的skills目录下创建了didichuxing_skill.py。import asyncio import json import logging from typing import Optional, Dict, Any from openclaw.skill import Skill, SkillTool from playwright.async_api import async_playwright, Page logger logging.getLogger(__name__) class DiDiChuxingSkill(Skill): 滴滴出行查询技能 name didi_chuxing description 查询滴滴打车当前订单的司机位置和预计到达时间。需要用户已登录滴滴小程序。 def __init__(self): super().__init__() self.browser None self.context None self.page: Optional[Page] None self.is_logged_in False async def setup(self): 初始化技能启动浏览器 logger.info(正在启动Playwright浏览器...) self.playwright await async_playwright().start() # 使用Chromium可指定executable_path self.browser await self.playwright.chromium.launch(headlessFalse) # 初期调试用非无头模式 # 模拟移动设备更接近小程序环境 iphone_12 self.playwright.devices[iPhone 12] self.context await self.browser.new_context(**iphone_12) self.page await self.context.new_page() logger.info(浏览器启动成功。) async def login_to_didi(self): 引导用户登录滴滴小程序此部分需手动操作一次 if self.is_logged_in: return True logger.info(请确保桌面版微信已登录然后手动完成滴滴小程序授权。) # 这里无法完全自动化登录因为涉及微信扫码和滴滴授权。 # 策略打开滴滴小程序首页等待用户手动操作。 await self.page.goto(https://xcx.didiglobal.com/) # 示例地址实际为小程序scheme或二维码 # 等待一个登录后的标志性元素出现比如“我的”按钮 try: await self.page.wait_for_selector(text我的, timeout120000) # 给2分钟手动操作 self.is_logged_in True logger.info(滴滴小程序登录状态确认。) return True except Exception as e: logger.error(f登录等待超时或失败: {e}) return False SkillTool( nameget_driver_location, description获取当前进行中订单的司机位置信息。返回位置描述和预计到达时间。, parameters{ auto_login: { type: boolean, description: 如果未登录是否尝试自动登录流程, required: False, default: True } } ) async def get_driver_location_tool(self, auto_login: bool True) - Dict[str, Any]: 工具函数供OpenClaw的LLM调用 try: if not self.page: await self.setup() if not self.is_logged_in and auto_login: login_ok await self.login_to_didi() if not login_ok: return {error: 滴滴小程序登录失败请手动检查。} # 1. 跳转到我的行程页面 await self.page.goto(滴滴小程序我的行程页面URL或通过点击导航) # 这里需要实际分析小程序页面结构使用playwright定位并点击 # await self.page.click(selector-for-我的行程) # 2. 查找第一个进行中的订单 # await self.page.wait_for_selector(selector-for-进行中订单) # order_card await self.page.query_selector(selector-for-第一个订单) # await order_card.click() # 3. 在订单详情页抓取位置信息 # 假设位置信息在一个class为.driver-location的div里 # location_element await self.page.wait_for_selector(.driver-location) # location_text await location_element.inner_text() # 4. 抓取预计到达时间 # eta_element await self.page.wait_for_selector(.eta-time) # eta_text await eta_element.inner_text() # 由于实际选择器需要动态分析这里返回模拟数据 # 真实开发中你需要使用 playwright 的代码录制功能或手动分析页面来获取准确选择器。 simulated_data { status: success, order_id: SIM202310270001, driver_location: 北京市海淀区中关村大街59号附近, driver_distance: 约1.2公里, estimated_arrival_time: 5分钟, map_snapshot_url: data:image/png;base64,... # 可以截图保存为base64 } logger.info(f成功查询到司机位置: {simulated_data}) return simulated_data except Exception as e: logger.exception(查询司机位置时发生异常) return {error: f查询失败: {str(e)}, status: error} async def cleanup(self): 清理资源 if self.context: await self.context.close() if self.browser: await self.browser.close() if self.playwright: await self.playwright.stop()4.3 技能注册与测试将写好的Skill文件放到OpenClaw的技能目录后需要在OpenClaw中注册它。通常可以通过配置文件或管理界面添加。在OpenClaw的Web UI的技能管理页面添加自定义技能路径然后刷新。测试技能是否生效可以在OpenClaw的聊天窗口输入“didi_chuxing帮我看看我的车到哪了”。OpenClaw的LLM应该能识别出这个指令并调用get_driver_location_tool工具。初期由于我们返回的是模拟数据你会看到固定的位置信息。但这证明了Skill的链路是通的。核心难点与避坑指南页面选择器不稳定小程序或App的UI经常更新导致写死的CSS选择器失效。解决方案是使用更鲁棒的定位方式如结合text、xpath以及>import requests import json async def send_feishu_message(webhook_url: str, title: str, content: dict): 发送消息到飞书群 message { msg_type: interactive, card: { elements: [{ tag: div, text: { content: f**司机位置**{content.get(driver_location)}\n**距离**{content.get(driver_distance)}\n**预计到达**{content.get(estimated_arrival_time)}, tag: lark_md } }], header: { title: { content: title, tag: plain_text } } } } try: resp requests.post(webhook_url, jsonmessage, timeout5) resp.raise_for_status() logger.info(飞书消息发送成功) except Exception as e: logger.error(f发送飞书消息失败: {e}) # 在 get_driver_location_tool 函数末尾返回结果前添加 asyncio.create_task(send_feishu_message(FEISHU_WEBHOOK_URL, 滴滴出行助手, simulated_data))6.2 实现定时查询与主动推送为了实现“每分钟查询并条件推送”我需要一个定时任务调度器。可以在OpenClaw技能外单独写一个Python脚本利用apscheduler或celery库。# scheduler.py import asyncio from apscheduler.schedulers.asyncio import AsyncIOScheduler from didichuxing_skill import DiDiChuxingSkill scheduler AsyncIOScheduler() didi_skill DiDiChuxingSkill() async def periodic_check(): 定时查询任务 await didi_skill.setup() # 确保技能已初始化 result await didi_skill.get_driver_location_tool(auto_loginFalse) # 假设登录态已持久化 if result.get(status) success: distance result.get(driver_distance, ) # 简单解析距离字符串例如“约1.2公里” try: km float(distance.replace(约, ).replace(公里, )) if km 1.0: # 小于1公里时触发通知 await send_feishu_message(WEBHOOK_URL, 司机快到了, result) except ValueError: pass async def main(): await didi_skill.login_to_didi() # 启动时先登录一次 scheduler.add_job(periodic_check, interval, minutes1) scheduler.start() # 保持主程序运行 await asyncio.Event().wait() if __name__ __main__: asyncio.run(main())这个脚本独立于OpenClaw主服务运行专门负责定时任务。它复用我们写的Skill代码来查询并根据业务逻辑决定是否推送。6.3 性能优化与稳定性保障项目跑起来后还要考虑长期运行的稳定性。资源管理Playwright浏览器实例比较耗内存。确保脚本在查询间隙能正确休眠并在异常退出时能清理浏览器进程避免僵尸进程。错误重试与降级网络波动、页面加载慢都会导致失败。在Skill的工具函数里加入重试机制如tenacity库并设置超时。如果多次重试失败返回一个友好的错误信息而不是让整个智能体卡死。日志与监控给关键步骤加上详细的日志logging模块方便排查问题。可以记录每次查询的时间、结果、耗时。如果部署在服务器上可以用systemd或supervisor来管理进程保证服务意外退出后能自动重启。隐私安全这个方案需要保持微信登录状态。务必确保服务器安全docker-compose.yml和环境变量中的敏感信息如API密钥不要提交到代码仓库。可以考虑使用secret管理或环境变量文件。7. 常见问题与故障排查实录在实际搭建和运行过程中我遇到了不少问题这里把典型问题和解决方案整理出来希望能帮你少走弯路。7.1 OpenClaw与Ollama连接失败问题OpenClaw Web UI提示“无法连接到模型”或“模型不可用”。排查在OpenClaw容器内执行ping 宿主机IP和curl http://宿主机IP:11434/api/tags。如果ping不通是网络问题如果curl失败但ping通是端口或服务问题。检查Ollama容器是否正在运行docker ps | grep ollama。检查宿主机的防火墙sudo ufw status。确保11434端口对Docker网络开放通常ufw默认会允许Docker流量但最好确认。解决网络问题在docker-compose.yml中为openclaw服务添加network_mode: host或者创建一个自定义Docker网络让两个容器共享。服务问题重启Ollama容器docker restart ollama并查看日志docker logs ollama。7.2 Playwright自动化被滴滴/微信检测问题脚本运行时页面弹出验证码或者直接提示“操作过于频繁请稍后再试”。排查在headlessFalse模式下观察自动化操作过程。是否鼠标移动轨迹是直线、点击间隔完全一致这些是典型的机器行为特征。解决添加人性化延迟在点击、输入等操作前后使用await asyncio.sleep(random.uniform(0.5, 2))加入随机等待时间。模拟鼠标移动Playwright可以模拟更真实的鼠标轨迹但代码较复杂。初期可以尝试在launch参数中添加args[--disable-blink-featuresAutomationControlled]。降低查询频率定时任务不要设置得太密集个人使用建议1-2分钟一次。使用更稳定的接口如果技术允许可以尝试寻找滴滴小程序中用于渲染地图的、带有位置信息的内部接口通过浏览器开发者工具Network面板寻找这比解析UI更稳定。但请注意合规性。7.3 OpenClaw的LLM不调用自定义Skill问题在聊天框输入指令后LLM只是普通聊天回复没有触发工具调用。排查技能是否加载成功在OpenClaw的管理界面查看技能列表确认didi_chuxing技能状态为“已启用”。工具描述是否清晰检查SkillTool装饰器中的description和parameters描述。LLM依赖这些描述来决定是否以及如何调用。描述要尽可能准确、具体。系统提示词是否有效确认系统提示词中明确提到了技能的使用场景和调用方式。可以尝试简化提示词只保留最核心的指令。模型能力不同的LLM工具调用能力差异很大。Qwen2.5-7B的工具调用能力不错但如果问题依旧可以尝试换用更大的14B模型或者在提示词中更强制地要求它调用工具例如“你必须使用didi_chuxing技能来回答这个问题”。解决打开OpenClaw的调试日志查看LLM接收到的提示词和生成的响应。有时候LLM生成了工具调用但格式不对被框架拒绝了。根据日志调整提示词或工具描述。7.4 技能执行超时或卡死问题工具调用后长时间没有响应最终超时。排查浏览器启动慢首次启动Playwright浏览器和加载页面可能耗时较长。适当增加工具调用的超时时间在OpenClaw技能配置或工具装饰器中设置。页面元素未加载wait_for_selector等待的元素可能因为网络慢或页面结构变化而一直不出现。增加等待超时时间并使用更宽松的选择器。异步函数错误确保Skill中所有可能耗时的操作如网络请求、页面等待都正确使用了await否则会阻塞事件循环。解决在Skill代码中添加超时控制并使用try...except捕获异常返回明确的错误信息。这个项目从构思到实现让我对AI智能体的落地有了更深的体会。它不是一个炫技的玩具而是一个真正能融入生活工作流、解决具体痛点的工具。虽然目前这个滴滴查询助手还有很多可以优化的地方比如支持更多打车平台、实现更精准的ETA计算、甚至自动规划上车点但它已经证明了OpenClaw这类框架在连接AI与真实世界服务上的巨大潜力。最大的收获不是代码本身而是这套“LLM理解 Skill执行”的设计范式它清晰地划定了边界让复杂任务的自动化变得可设计、可实现。如果你也对自动化感兴趣不妨从一个小痛点开始用OpenClaw试试看这个过程本身就充满了探索的乐趣。