Files
aiData/Apps/AiTeJiYiChong/Crawler.py

101 lines
3.1 KiB
Python
Raw Normal View History

2026-01-12 14:50:20 +08:00
# 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())