# coding=utf-8 import asyncio import logging import uuid import os import sys import time from PIL import Image # 将项目根目录添加到 sys.path project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) if project_root not in sys.path: sys.path.append(project_root) import uiautomator2 as u2 from Apps.AiTeJiYiChong import Kit from Apps.AiTeJiYiChong.Kit import take_screenshot from Util.RedisKit import RedisKit from Apps.AiTeJiYiChong.Service import AiTeJiYiChongService from Config.Config import TEMP_IMAGE_DIR from Apps.AiTeJiYiChong.Config.Setting import ( SCROLL_DISTANCE_RATIO, MAX_SCROLLS, REDIS_STATION_EXPIRE, WAIT_AFTER_SCROLL, MAX_CRAWL_DISTANCE ) logger = logging.getLogger("AiTeJiYiChongCrawler") async def get_station_list(d, service, max_scrolls=MAX_SCROLLS): """ 获取场站列表并处理翻页 """ redis_kit = RedisKit() window_size = d.window_size() w, h = window_size[0], window_size[1] device_info = d.info device_info['width'] = w device_info['height'] = h logger.info(f"开始爬取列表,设备: {device_info.get('productName')} | 分辨率: {w}x{h}") for i in range(max_scrolls + 1): logger.info(f"正在处理第 {i + 1} 页...") # 1. 拍摄截图 image_uuid = str(uuid.uuid4()) screenshot_path = take_screenshot(d, image_uuid, save_dir=TEMP_IMAGE_DIR) logger.info(f"列表页截图已完成: {screenshot_path}") # 2. 执行图形学分析,生成 _flag.jpg, _vl.jpg 和 .json logger.info("正在执行图形学切片分析...") json_data = Kit.crop_cards_from_image(screenshot_path) # 3. 调用 VL 模型识别并保存数据 # 这里的 service.process_station_list_vl 应该支持传入 json_data 或直接读取图片 stations = await service.process_station_list_vl(screenshot_path, device_info=device_info) logger.info(f"本页识别到 {len(stations)} 个场站") if not stations: logger.warning("本页未识别到任何场站,可能已到底或加载中") # 如果连续几页没数据可以考虑跳出,这里先简单处理 # 3. 翻页滑动 logger.info("执行翻页滑动...") start_x, start_y = w // 2, int(h * 0.8) end_x, end_y = w // 2, int(h * (0.8 - SCROLL_DISTANCE_RATIO)) d.swipe(start_x, start_y, end_x, end_y, duration=0.5) await asyncio.sleep(WAIT_AFTER_SCROLL) logger.info("达到最大翻页次数,爬取结束。") return True async def main(service=None, do_cleanup=True): """ 爬虫主入口 """ if do_cleanup: Kit.clear_temp_dir() if service is None: service = AiTeJiYiChongService() await service.init_db() d = u2.connect() try: await get_station_list(d, service) return True except Exception as e: logger.error(f"爬取过程中出现异常: {e}") return False finally: # 如果是内部初始化的 service,则在此关闭 pass if __name__ == "__main__": asyncio.run(main())