'commit'
This commit is contained in:
@@ -110,13 +110,13 @@ async def is_already_crawled(redis_kit, station_name):
|
||||
return False
|
||||
|
||||
|
||||
async def analyze_prices_background(service, station_name, image_paths):
|
||||
async def analyze_prices_background(service, station_name, image_paths, device_info=None):
|
||||
"""
|
||||
后台异步处理价格图片分析
|
||||
"""
|
||||
try:
|
||||
# 使用多图解析并去重
|
||||
all_rows = await ReadImageKit.parse_price_schedule_multi(station_name, image_paths)
|
||||
all_rows = await ReadImageKit.parse_price_schedule_multi(station_name, image_paths, device_info=device_info)
|
||||
|
||||
if all_rows:
|
||||
# 24小时铺平
|
||||
@@ -155,6 +155,7 @@ async def get_station_list(d, service, uploader, max_scrolls=MAX_SCROLLS):
|
||||
|
||||
background_tasks = []
|
||||
last_list_md5 = None
|
||||
no_new_data_count = 0
|
||||
|
||||
for i in range(max_scrolls + 1):
|
||||
logger.info(f"正在处理第 {i + 1} 页...")
|
||||
@@ -203,6 +204,7 @@ async def get_station_list(d, service, uploader, max_scrolls=MAX_SCROLLS):
|
||||
|
||||
# 5. 匹配几何卡片与 VL 识别结果 (XinDianTu 的 parse_vl_image 已经按顺序返回了)
|
||||
# 这里的 stations 列表长度应该与 json_metadata["cards"] 对应
|
||||
new_stations_processed = 0
|
||||
if json_metadata.get("cards") and stations:
|
||||
for idx, card in enumerate(json_metadata["cards"]):
|
||||
# 检查索引是否越界 (VL 模型可能返回的数组长度不一致)
|
||||
@@ -216,6 +218,7 @@ async def get_station_list(d, service, uploader, max_scrolls=MAX_SCROLLS):
|
||||
logger.info(f"场站 {station_name} 匹配到已处理记录,跳过。")
|
||||
continue
|
||||
|
||||
new_stations_processed += 1
|
||||
click_x, click_y = card["click_point"]
|
||||
logger.info(f"准备处理第 {idx + 1} 个场站: {station_name}, 点击坐标: ({click_x}, {click_y})")
|
||||
|
||||
@@ -223,6 +226,9 @@ async def get_station_list(d, service, uploader, max_scrolls=MAX_SCROLLS):
|
||||
|
||||
# 等待二级页面加载
|
||||
await asyncio.sleep(WAIT_DETAIL_PAGE_LOAD)
|
||||
|
||||
should_back_to_list = True
|
||||
|
||||
|
||||
# 截取二级页面图
|
||||
detail_uuid = str(uuid.uuid4())
|
||||
@@ -272,12 +278,38 @@ async def get_station_list(d, service, uploader, max_scrolls=MAX_SCROLLS):
|
||||
|
||||
# 【异步优化】后台处理价格
|
||||
logger.info(f"已启动后台分析价格页: {station_name}")
|
||||
task_price = asyncio.create_task(analyze_prices_background(service, station_name, price_screenshots))
|
||||
task_price = asyncio.create_task(analyze_prices_background(service, station_name, price_screenshots, device_info=device_info))
|
||||
background_tasks.append(task_price)
|
||||
|
||||
# 从三级页面返回二级页面
|
||||
d.press("back")
|
||||
await asyncio.sleep(0.5)
|
||||
|
||||
# 检查返回后的页面状态,防止多重返回导致退出到搜索页
|
||||
check_back_path = take_screenshot(d, f"check_back_{detail_uuid}", save_dir=TEMP_IMAGE_DIR)
|
||||
|
||||
# 1. 与列表页对比 (使用列表页的排除比例)
|
||||
check_list_md5 = Kit.get_image_content_md5(
|
||||
check_back_path,
|
||||
top_ratio=SAFE_EXCLUDE_RATIO,
|
||||
bottom_ratio=BOTTOM_SAFE_EXCLUDE_RATIO
|
||||
)
|
||||
|
||||
# 2. 与详情页对比 (使用默认排除比例,与 before_click_md5 一致)
|
||||
check_detail_md5 = Kit.get_image_content_md5(check_back_path)
|
||||
|
||||
if os.path.exists(check_back_path): os.remove(check_back_path)
|
||||
|
||||
if check_list_md5 == current_md5:
|
||||
logger.info("检测到已直接返回列表页,跳过后续返回操作。")
|
||||
should_back_to_list = False
|
||||
elif check_detail_md5 == before_click_md5:
|
||||
logger.info("检测到返回详情页,需执行第二次返回。")
|
||||
should_back_to_list = True
|
||||
else:
|
||||
logger.warning(f"返回后状态未知 (ListMD5:{check_list_md5[:8]} vs {current_md5[:8]}, DetailMD5:{check_detail_md5[:8]} vs {before_click_md5[:8]}),默认执行返回。")
|
||||
should_back_to_list = True
|
||||
|
||||
else:
|
||||
logger.warning(f"点击 '{station_name}' 的 '全部时段' 按钮后页面无明显变化,跳过三级页面处理。")
|
||||
|
||||
@@ -286,9 +318,10 @@ async def get_station_list(d, service, uploader, max_scrolls=MAX_SCROLLS):
|
||||
else:
|
||||
logger.info(f"场站 {station_name} 未发现 '全部时段' 按钮。")
|
||||
|
||||
# 从二级页面返回
|
||||
d.press("back")
|
||||
await asyncio.sleep(WAIT_BACK_TO_LIST)
|
||||
# 从二级页面返回 (仅当确实需要返回时)
|
||||
if should_back_to_list:
|
||||
d.press("back")
|
||||
await asyncio.sleep(WAIT_BACK_TO_LIST)
|
||||
|
||||
# 记录 Redis 去重 (仅按名称去重)
|
||||
cleaned = Kit.clean_station_name(station_name)
|
||||
@@ -301,6 +334,15 @@ async def get_station_list(d, service, uploader, max_scrolls=MAX_SCROLLS):
|
||||
logger.error(f"后台任务异常: {t.exception()}")
|
||||
background_tasks.remove(t)
|
||||
|
||||
if stations and new_stations_processed == 0:
|
||||
no_new_data_count += 1
|
||||
logger.info(f"本页所有场站均已处理过,连续 {no_new_data_count} 页无新数据。")
|
||||
if no_new_data_count >= 3:
|
||||
logger.info("连续 3 页无新数据,判定为已到底或重复循环,提前结束。")
|
||||
break
|
||||
else:
|
||||
no_new_data_count = 0
|
||||
|
||||
# 6. 翻页
|
||||
logger.info("执行翻页滑动...")
|
||||
d.swipe_ext("up", scale=SCROLL_DISTANCE_RATIO)
|
||||
|
||||
Reference in New Issue
Block a user