Files
aiData/Apps/AiTeJiYiChong/Doc/流程说明.md
HuangHai 2051cb61c2 'commit'
2026-01-12 20:39:06 +08:00

75 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 艾特吉易充数据抓取流程说明文档
本文件详细记录了艾特吉易充(微信小程序)数据抓取爬虫的设计架构、抓取流程及关键技术实现。
---
## 1. 项目概述
本爬虫旨在自动化抓取“艾特吉易充”小程序中的充电场站信息,包括场站名称、地址、充电枪状态、实时价格以及 24 小时分时价格表。
## 2. 核心抓取流程
爬虫采用“列表 -> 详情 -> 价格 -> 返回 -> 列表”的闭环循环逻辑。
### 2.1 第一级:场站列表页
- **操作**: 自动滚动列表,每屏截取一张大图。
- **识别方法**:
- **图形学切片**: 使用 OpenCV 识别图片中的白色卡片区域(几何卡片),将其裁剪为独立的小图。
- **VL 并行识别**: 对裁剪出的每个场站小图,并行调用 `Qwen-VL` 模型提取名称、价格、枪数等信息。
- **坐标映射**: 将 VL 识别结果直接映射回原始几何卡片的点击坐标。
- **关键点**: 通过几何切片降低 VL 模型的识别负担,通过并行调用提高整体处理速度。
### 2.2 第二级:场站详情页
- **进入**: 点击列表页卡片。
- **操作**: 截取详情页全图。
- **识别方法**:
- **异步识别**: 截图后立即启动 `asyncio.create_task` 在后台调用 VL 模型提取地址和基础信息。
- **模板匹配**: 使用 OpenCV 查找“分时价格”图标(`timePrice.jpg`)的坐标。
- **关键点**: UI 流程不等待 VL 模型返回,直接寻找入口进入下一级。
### 2.3 第三级:价格详情页
- **进入**: 点击详情页中的分时价格入口。
- **操作**: 截取价格列表,若列表过长则执行滑动截图,利用 MD5 校验判断是否滑动到底部。
- **识别方法**:
- **异步识别**: 截图完成后,UI 立即执行 `d.press("back")` 返回列表页,所有截图交给后台任务处理。
- **数据规整**: 后台任务调用 VL 模型识别各时段价格,并使用 `ReadImageKit.expand_schedule_to_24h` 将不规则时段规整为 24 小时整点数据。
---
## 3. 关键技术点
### 3.1 异步并发设计 (Decoupling)
- **实现方式**: 使用 `AsyncOpenAI` 客户端和 `asyncio.create_task`。
- **为什么要异步?**:
1. **提高吞吐量**: VL 模型响应通常需要 3-8 秒。如果同步等待,爬取一个场站可能需要 20 秒以上。异步化后,手机 UI 可以在后台分析的同时继续操作。
2. **用户体验**: UI 操作(点击、滑动、返回)是连续的,不会因为网络请求波动而卡顿。
- **任务追踪**: 在 `Crawler.py` 中维护 `background_tasks` 列表,在每页结束时清理已完成任务,并在整个爬取结束时使用 `asyncio.gather` 等待残余任务。
### 3.2 场站去重策略
- **按名称去重**: 仅依据列表显示的场站名称进行去重,不再使用前缀或模糊匹配。
- **处理规则**:
- 名称先经 `clean_station_name` 去掉尾部省略号与空格,例如 `AAABBB...` → `AAABBB`;
- 首次遇到该名称时处理并写入 Redis 键 `crawled:aite:{name}`;
- 后续再遇到同名(包括省略号截断的同名)直接跳过,不再点击进入详情页。
- **设计原因**: 逻辑直白、符合业务预期,降低模糊匹配带来的误判风险。
- **一致性说明**: 新电途项目采用同样的按名称去重策略以保持跨项目行为一致。
### 3.3 坐标系转换
- **VL 坐标**: 0-1000 的归一化坐标。
- **UI 坐标**: 屏幕像素坐标(如 1080x2400)。
- **转换公式**: `px = val * screen_size / 1000`。用于将 VL 识别的场站位置映射到屏幕实际可点击位置。
### 3.4 鲁棒性设计
- **JSON 提取器**: `ReadImageKit._extract_json` 采用递归和 `raw_decode` 策略,能够从 VL 模型输出的杂乱文本中精准提取 JSON 内容,容忍模型输出的说明文字。
- **图片读写**: `Kit.py` 封装了支持中文路径的图片读写方法(`np.fromfile` / `cv2.imencode`),并增加了空文件校验,防止因并发读写导致的 `cv2` 崩溃。
---
## 4. 给研发人员的建议
1. **调试模式**: 开启 `logging.INFO` 级别可以观察到 VL 模型的完整响应。
2. **环境依赖**: 确保 `uiautomator2` 已正确连接 Android 设备。
3. **API 消耗**: 异步调用会增加 API 并发压力,请确保使用的 API Key 具有足够的 QPS 限额。
4. **内存管理**: 后台任务会持有图片路径,处理完成后务必调用 `os.remove` 清理临时图片。
---
*文档更新日期:2026-01-12*