olin преди 3 седмици
родител
ревизия
2377808c19
променени са 1 файла, в които са добавени 212 реда и са изтрити 0 реда
  1. 212 0
      tbsg/README.md

+ 212 - 0
tbsg/README.md

@@ -0,0 +1,212 @@
+# tbsg — 饿了么闪购店铺采集
+
+OCR + AI 驱动的 Android 端到端自动化,从搜索到二维码解析全流程。
+
+## 目录结构
+
+```
+tbsg/
+├── main.py                       # 主入口(920行):步骤编排 + 验证码处理 + 二维码解析
+├── ai_helper.py                  # DeepSeek AI:页面分类 / 店铺解析 / 坐标定位
+│
+├── steps/
+│   ├── executor.py               # SafeExecutor:uiautomator2 安全执行器(点击/滑动/输入/重连)
+│   └── ocr.py                    # OCR 类:RapidOCR 封装(裁剪/压缩/置信度过滤)
+│
+├── detect_slider_button.py       # 滑块按钮检测:HSV 橙色识别 + 轮廓筛选
+├── detect_captcha_edge.py        # 验证码缺口边缘检测:橙色覆盖层最左 X 坐标
+│
+├── yzm/
+│   └── tmp_captcha_test2.py      # 滑块验证码破解:TouchPipe 压感 + 轨迹模拟 + jfbym API
+│
+└── files/
+    ├── captcha1.png              # 验证码模板(用于模板匹配检测)
+    ├── line.png                  # 滑块辅助图
+    └── share.png                 # 分享按钮辅助图
+```
+
+---
+
+## 运行
+
+```bash
+cd tbsg
+python main.py                        # 全流程,默认搜索"矿泉水"
+python main.py step1                  # 仅步骤1:打开 App
+python main.py step2 金活正红花油      # 仅步骤2:搜索指定关键词
+python main.py step3                  # 仅步骤3:遍历店铺列表
+python main.py --device DEVICE_ID     # 指定设备
+```
+
+**默认设备:** `T4VK4LM7AAUOV8AY`(多设备时交互选择)
+
+---
+
+## 全流程(cmd="all")
+
+### 步骤 1:打开 App
+
+```
+1. app_stop("me.ele") → 关闭饿了么
+2. app_start("me.ele") → 重新启动
+3. sleep(5s) → 等加载
+4. OCR 识别底部 12% 区域 → 检测"我的"确认进入成功
+```
+
+**核心代码:** `step1_open_app(ex)` — 第106行
+
+### 步骤 2:搜索商品
+
+```
+阶段0 — 进入买药频道
+  1. OCR 全屏识别 → 找"看病买药"按钮 → 点击 → sleep(3s)
+
+阶段1 — 点击搜索栏
+  2. OCR 顶部 30% 区域 → 找"搜索" → 偏移 -120px 点击输入框 → sleep(3s)
+
+阶段2 — 输入关键词
+  3. OCR 确认进入搜索页(搜索文字位置是否移动)
+  4. 偏移 -180px 点击输入框 → 聚焦
+  5. set_input_ime(True) → send_keys(keyword) → 点击"搜索"
+  6. OCR 验证:检测"筛选"/"快递"确认搜索结果页
+
+阶段3 — 切换到快递配送
+  7. 若检测到"快递"→ 点击切换(确保全国范围搜索)
+```
+
+**核心代码:** `step2_search(ex, keyword)` — 第135行
+
+### 步骤 3:遍历店铺列表
+
+```
+while True:
+  1. 截图 → OCR → AI 解析店铺列表(店名/商品/价格/坐标)
+  2. 过滤:店名含中文或字母 + 有价格 = 有效店铺
+  
+  3. 逐个点击店铺:
+     a. 去重检查(店名+价格 key)
+     b. 点击进入店铺
+     c. 调用 step4_parse_qr() 获取二维码链接
+     d. 返回搜索页(最多3次 back)
+  
+  4. 一个批次处理完 → 滑动到倒数第二张卡片位置
+  5. 连续3批无新店铺 → 结束
+
+输出:
+  最终结果表(店铺名 / 商品 / 价格 / 链接)
+```
+
+**核心代码:** `step3_swipe_and_enter(ex, keyword)` — 第782行
+
+**滑动方式:** ADB `input swipe` 分3段手指滑动(模拟真人),非 uiautomator2 swipe
+
+### 步骤 4:进入店铺 → 解析二维码
+
+```
+1. 等待加载(sleep 6s)
+   └─ 异常处理:验证码检测(模板匹配 + OCR关键词)→ 自动破解
+   └─ 安全验证弹窗 → 反复 back 退出
+
+2. 确认在店铺页:OCR 检测"刚刚搜过" + "评价"
+
+3. AI 定位商品标题坐标:
+   a. 截图 → OCR → 返回所有文字块坐标
+   b. DeepSeek AI 匹配商品标题 → 返回点击坐标
+   c. 最多重试3次(每次重新OCR+AI)
+
+4. 点击商品标题 → 进入详情页
+   └─ 验证:检测"加入购物车"/"立即购买"关键字
+   └─ 验证码拦截 → 自动处理
+
+5. 找右上角"分享"按钮 → 点击 → 二维码弹窗 → 截图
+
+6. pyzbar 解析二维码 → 返回 URL
+```
+
+**核心代码:** `step4_parse_qr(ex, product_title, shop_name)` — 第342行
+
+---
+
+## 验证码处理
+
+### 检测方式(双重)
+
+1. **模板匹配** — `captcha1.png` 5种算法(灰度/边缘/直方图/高斯/二值化),阈值 0.30
+2. **OCR 关键词** — "拖动滑块"/"请按住滑块"/"安全验证"
+
+### 破解方式(`yzm/tmp_captcha_test2.py`)
+
+| 步骤 | 说明 |
+|------|------|
+| 1. 截图 | 截取验证码弹窗 |
+| 2. 滑块定位 | `detect_slider_button()` — HSV 橙色检测 |
+| 3. 缺口定位 | `detect_captcha_edge()` — 橙色覆盖层左边缘 |
+| 4. 计算距离 | 缺口左边缘 - 滑块中心 X |
+| 5. 轨迹生成 | 加速→匀速→减速 + 随机扰动 |
+| 6. 执行滑动 | TouchPipe(ATX 9008端口压感通道) |
+| 7. jfbym API | 云码平台兜底(`http://api.jfbym.com`) |
+
+**最多重试 5 次**,失败后等待人工处理。
+
+---
+
+## 核心模块详解
+
+### SafeExecutor(`steps/executor.py`)
+
+封装 uiautomator2,提供安全操作:
+
+| 方法 | 说明 |
+|------|------|
+| `tap(x, y)` | 坐标点击 |
+| `swipe(distance)` | 分多段模拟真人滑动(X轴±30px 随机偏移) |
+| `input_text(xpath, text)` | 清空再输入(模拟打字间隔) |
+| `safe_click(xpath)` | 点击 + 验证码检测 + 自动处理 |
+| `No_slider()` | 验证码检测 + `_solve_slider()` 自动破解 |
+| `is_connected()` | 连接检测 + 自动重启 atx-agent |
+| `_recover_service()` | stop → start atx-agent → reconnect |
+
+### OCR(`steps/ocr.py`)
+
+基于 RapidOCR(`rapidocr_onnxruntime`),无需 GPU。
+
+| 参数 | 说明 |
+|------|------|
+| `rect` | 裁剪区域 `[left, top, right, bottom]` |
+| `confidence` | 置信度阈值(默认 0.1) |
+| `pattern` | 正则过滤 |
+| `detail` | `'all'`/`'text'`/`'first'` |
+
+- 大图自动压缩到 960px 防止 OOM
+- 矩形坐标自动映射回原始尺寸
+
+### AIParser(`ai_helper.py`)
+
+调用 DeepSeek API,三个核心功能:
+
+| 方法 | 输入 | 输出 |
+|------|------|------|
+| `parse_shops()` | OCR 原始结果 | 店铺列表(店名/商品/价格/坐标) |
+| `check_page()` | OCR 文字列表 | 页面类型(`normal`/`risk`/`qrcode`) |
+| `_call()` | system_prompt + user_prompt | AI 响应 JSON |
+
+**API 地址:** `https://ai-api.dfwy.tech/v1/messages`  
+**模型:** `deepseek-v4-flash-nothinking`
+
+---
+
+## 依赖
+
+```bash
+pip install uiautomator2 opencv-python rapidocr-onnxruntime Pillow numpy requests pyzbar
+```
+
+- Android 真机连接 ADB
+- atx-agent 已安装于设备
+- DeepSeek API Key(环境变量 `DEEPSEEK_API_KEY` 或 `config.json`)
+
+---
+
+## 注意事项
+
+- `yzm/tmp_captcha_test2.py` 含云码平台 Token