—基于真实存在的 OpenManus(开源 Agent 框架)+ Qwen2.5-VL(本地视觉模型)+ PyAutoGUI(鼠标控制),在 Ubuntu 22.04 上实现你要的网页登录+鼠标点击签到功能。
方案总览
| 组件 | 选型 | 作用 |
|---|---|---|
| OS | Ubuntu 22.04 LTS | 基础环境 |
| 视觉模型 | Qwen2.5-VL-7B/14B (Int4 量化) | 识别按钮坐标、验证码、页面元素 |
| Agent 框架 | OpenManus (开源) | 任务规划、决策逻辑 |
| 鼠标控制 | PyAutoGUI | 物理级鼠标移动/点击(跨应用) |
| 浏览器 | Playwright (Chromium) | 网页自动化、登录态保持 |
核心逻辑:
Agent 看到屏幕 → Qwen2.5-VL 识别"登录按钮坐标" → PyAutoGUI 移动鼠标点击 → 输入账号 → 找到"签到按钮" → 点击完成
从零开始部署步骤
1. 系统环境准备(Ubuntu 22.04)
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装基础依赖
sudo apt install -y python3-pip python3-venv git curl wget \
libgl1-mesa-glx libglib2.0-0 libsm6 libxext6 libxrender-dev \
scrot # 截图工具,PyAutoGUI 依赖
# 安装 Node.js 18+(OpenManus 需要)
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
# 安装 Ollama(部署本地 Qwen2.5-VL)
curl -fsSL https://ollama.com/install.sh | sh
# 启动 Ollama 服务(后台运行)
sudo systemctl start ollama
sudo systemctl enable ollama
2. 部署 Qwen2.5-VL(本地视觉模型)
Qwen2.5-VL 是阿里开源的视觉语言模型,能识别图片中的 UI 元素并返回坐标。
# 拉取 Qwen2.5-VL 7B 量化版(约 4.5GB,需 8GB+ VRAM,无显卡用纯 CPU 极慢)
ollama pull qwen2.5:7b
# 验证部署
ollama run qwen2.5:7b "描述这张图片" # 测试对话能力
关键配置:OpenManus 需要模型支持 OpenAI-compatible API,Ollama 默认提供 http://localhost:11434/v1 端点。
3. 安装 OpenManus 并配置本地模型
# 克隆 OpenManus
git clone https://github.com/man-group/OpenManus.git
cd OpenManus
# 安装 Python 依赖
pip3 install -e .
# 创建配置文件
mkdir -p ~/.config/openmanus
cat > ~/.config/openmanus/config.toml << 'EOF'
[llm]
model = "qwen2.5:7b"
base_url = "http://localhost:11434/v1"
api_key = "ollama" # Ollama 不需要真实 key,但字段必须存在
temperature = 0.2 # 降低随机性,确保坐标准确
max_tokens = 2048
[browser]
headless = false # 必须 false,才能看到浏览器并被 PyAutoGUI 控制
EOF
4. 开发自定义 Tool:鼠标控制与视觉识别
OpenManus 默认没有物理鼠标控制能力,需自行扩展。
创建文件 openmanus/tools/mouse_control.py:
import pyautogui
import time
import base64
from io import BytesIO
from PIL import Image
from typing import Tuple, Optional
from openmanus.tools.base import BaseTool
class MouseControlTool(BaseTool):
name = "mouse_control"
description = "物理鼠标控制:移动、点击、截图。支持视觉定位。"
def __init__(self):
# 禁用 PyAutoGUI 的安全边界(防止鼠标移到角落报错)
pyautogui.FAILSAFE = False
# 获取屏幕尺寸
self.screen_width, self.screen_height = pyautogui.size()
async def screenshot(self) -> str:
"""截图并转为 base64,供 Qwen-VL 分析"""
screenshot = pyautogui.screenshot()
buffered = BytesIO()
screenshot.save(buffered, format="PNG")
return base64.b64encode(buffered.getvalue()).decode()
async def get_coordinates_from_vlm(self, description: str, base64_image: str) -> Optional[Tuple[int, int]]:
"""
调用 Qwen2.5-VL 识别元素坐标
返回: (x, y) 屏幕坐标
"""
# 这里调用 Ollama API 进行视觉识别
import openai
client = openai.OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
response = client.chat.completions.create(
model="qwen2.5:7b",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": f"在图片中找到'{description}'的位置,返回屏幕坐标(x,y)。只返回数字格式:x,y,不要其他文字。"},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{base64_image}"}}
]
}
]
)
try:
coord_str = response.choices[0].message.content.strip()
x, y = map(int, coord_str.split(','))
# 边界检查
x = max(0, min(x, self.screen_width))
y = max(0, min(y, self.screen_height))
return (x, y)
except:
return None
async def click(self, x: int, y: int):
"""移动鼠标并点击"""
pyautogui.moveTo(x, y, duration=0.5) # 0.5秒移动,避免被检测为机器人
time.sleep(0.1)
pyautogui.click()
time.sleep(0.5) # 等待页面响应
async def type_text(self, text: str):
"""模拟键盘输入"""
pyautogui.typewrite(text, interval=0.05) # 每个字符间隔 50ms,模拟人类
async def press_enter(self):
pyautogui.press('enter')
5. 编写签到 Agent 任务流
创建 signin_agent.py:
import asyncio
from mouse_control import MouseControlTool
from openmanus.tools.browser import BrowserTool
class SignInAgent:
def __init__(self):
self.mouse = MouseControlTool()
self.browser = BrowserTool()
async def run(self, url: str, username: str, password: str):
# 1. 启动浏览器并导航
await self.browser.navigate(url)
await asyncio.sleep(3) # 等待页面加载
# 2. 截图并找到"账号输入框"
screenshot = await self.mouse.screenshot()
coord = await self.mouse.get_coordinates_from_vlm("账号输入框/用户名输入框", screenshot)
if coord:
await self.mouse.click(*coord)
await self.mouse.type_text(username)
print(f"已输入账号在坐标: {coord}")
# 3. 找到密码框并输入
screenshot = await self.mouse.screenshot()
coord = await self.mouse.get_coordinates_from_vlm("密码输入框", screenshot)
if coord:
await self.mouse.click(*coord)
await self.mouse.type_text(password)
await self.mouse.press_enter()
print(f"已输入密码并提交")
await asyncio.sleep(3) # 等待登录
# 4. 寻找签到按钮(可能需滚动页面)
for attempt in range(3): # 尝试3次滚动查找
screenshot = await self.mouse.screenshot()
coord = await self.mouse.get_coordinates_from_vlm("签到按钮/Sign In Button", screenshot)
if coord:
await self.mouse.click(*coord)
print(f"已点击签到按钮,坐标: {coord}")
return "签到成功"
else:
# 向下滚动
pyautogui.scroll(-500)
await asyncio.sleep(1)
return "未找到签到按钮"
# 运行
if __name__ == "__main__":
agent = SignInAgent()
result = asyncio.run(agent.run(
url="https://your-signin-website.com",
username="your_username",
password="your_password"
))
print(result)
6. 运行与调试
# 安装 Playwright 浏览器(Chromium)
playwright install chromium
# 运行 Agent(需在图形界面下,SSH 不行,必须本地或 VNC)
python3 signin_agent.py
常见问题:
- 坐标不准:Qwen2.5-VL 7B 可能识别精度不足,建议换 14B 或调整提示词(要求返回中心点坐标)。
- 被反爬:网站检测 Selenium/Playwright,需加
stealth插件或换用undetected-chromedriver。 - 无头模式:若用 headless=True,PyAutoGUI 无法截图浏览器窗口,必须用 headed 模式。