This commit is contained in:
HuangHai
2026-01-14 13:58:51 +08:00
parent f4d3dada58
commit c5cc0595d4
3 changed files with 21 additions and 23 deletions

View File

@@ -196,11 +196,11 @@ class TeLaiDianCrawler(BaseCrawler):
""" """
在详情页提取价格和状态信息 在详情页提取价格和状态信息
""" """
# 1. 截取第一屏的基础信息图(名称、精确地址),并异步识别
first_screen_path = take_screenshot(d, f"tld_detail_basic_{int(time.time())}.jpg") first_screen_path = take_screenshot(d, f"tld_detail_basic_{int(time.time())}.jpg")
station_name = station_info.get("name") station_name = station_info.get("name")
address = station_info.get("address") address = station_info.get("address")
logger.info(f"已截取详情页首屏截图,启动异步基础信息识别任务: {station_name} | {address}") logger.info(f"[详情页] 进入 crawl_detail_logic,场站: {station_name} | 地址: {address}")
logger.info(f"[详情页] 已截取首屏截图,启动异步基础信息识别任务: {first_screen_path}")
async def analyze_basic_info_background(image_path, fallback_name, fallback_address): async def analyze_basic_info_background(image_path, fallback_name, fallback_address):
try: try:
@@ -219,25 +219,24 @@ class TeLaiDianCrawler(BaseCrawler):
asyncio.create_task(analyze_basic_info_background(first_screen_path, station_name, address)) asyncio.create_task(analyze_basic_info_background(first_screen_path, station_name, address))
# 2. 一次向上滑动,确保当前底部文字完全顶到上沿之外
w, h = d.window_size() w, h = d.window_size()
logger.info("执行一次向上滑动,将当前底部文字完全推至屏幕上沿之外...") logger.info("[详情页] 先执行一次较大的向上滑动,将详情内容上移一屏左右")
d.swipe(w * 0.5, h * 0.75, w * 0.5, h * 0.25, 0.8) d.swipe(w * 0.5, h * 0.8, w * 0.5, h * 0.3, 0.5)
await asyncio.sleep(1.5) await asyncio.sleep(1.0)
# 3. 使用模板 jgxx.jpg 匹配“价格信息 当前价”入口并点击
template_jgxx = os.path.join(os.path.dirname(__file__), "Template", "jgxx.jpg") template_jgxx = os.path.join(os.path.dirname(__file__), "Template", "jgxx.jpg")
entrance_point = None entrance_point = None
if os.path.exists(template_jgxx): if os.path.exists(template_jgxx):
logger.info(f"使用模板匹配价格入口: {template_jgxx}") logger.info(f"[详情页] 使用模板匹配价格入口: {template_jgxx},第 1 轮(只匹配一次)")
try: try:
match_res = d.image.match(template_jgxx) match_res = d.image.match(template_jgxx)
except Exception as e: except Exception as e:
match_res = None match_res = None
logger.error(f"模板匹配价格入口失败: {e}") logger.error(f"[详情页] 模板匹配价格入口失败: {e}")
if match_res: if match_res:
logger.info(f"[详情页] 第 1 轮模板匹配返回结果: {match_res}")
if hasattr(match_res, "point") and match_res.point: if hasattr(match_res, "point") and match_res.point:
entrance_point = match_res.point entrance_point = match_res.point
elif isinstance(match_res, dict): elif isinstance(match_res, dict):
@@ -248,26 +247,25 @@ class TeLaiDianCrawler(BaseCrawler):
elif isinstance(match_res, (list, tuple)) and len(match_res) >= 2: elif isinstance(match_res, (list, tuple)) and len(match_res) >= 2:
entrance_point = (match_res[0], match_res[1]) entrance_point = (match_res[0], match_res[1])
if entrance_point: if not entrance_point:
logger.info(f"通过 jgxx.jpg 成功找到价格入口,点击坐标: {entrance_point}") logger.error("[详情页] 未能通过 jgxx.jpg 找到价格入口,本次流程直接中止,需人工检查详情页布局或模板。")
d.click(int(entrance_point[0]), int(entrance_point[1])) raise RuntimeError("TeLaiDian: 价格入口模板匹配失败")
await asyncio.sleep(WAIT_DETAIL_PAGE_LOAD)
else: logger.info(f"[详情页] 通过 jgxx.jpg 成功找到价格入口,点击坐标: {entrance_point},即将进入电价页")
logger.warning("未能通过 jgxx.jpg 找到价格入口,使用坐标兜底点击页面中部偏下位置。") d.click(int(entrance_point[0]), int(entrance_point[1]))
d.click(w // 2, int(h * 0.45)) await asyncio.sleep(WAIT_DETAIL_PAGE_LOAD)
await asyncio.sleep(WAIT_DETAIL_PAGE_LOAD)
# 4. 进入分时电价页面后的处理 # 4. 进入分时电价页面后的处理
try: try:
logger.info("已点击进入价格详情,等待小程序自动滚动定位完成 (4秒)...") logger.info("[电价页] 已点击价格入口,等待小程序自动滚动定位完成 (4秒)...")
await asyncio.sleep(4.0) await asyncio.sleep(4.0)
logger.info("[电价页] 开始执行两次大幅向下拉动,目标是回到 00:00 时段顶部")
logger.info("执行两次大幅向下拉动,确保回到 00:00 时段顶部...") for idx in range(2):
for _ in range(2): logger.info(f"[电价页] 第 {idx+1} 次向下滑动(d.swipe_ext(\"down\", scale=0.9))")
d.swipe_ext("down", scale=0.9) d.swipe_ext("down", scale=0.9)
await asyncio.sleep(1.0) await asyncio.sleep(1.0)
except Exception as e: except Exception as e:
logger.error(f"处理分时电价页面初始状态失败: {e}") logger.error(f"[电价页] 处理分时电价页面初始状态失败: {e}")
# 5. 循环滑动抓取完整分时电价 # 5. 循环滑动抓取完整分时电价
all_prices = [] all_prices = []
@@ -277,7 +275,7 @@ class TeLaiDianCrawler(BaseCrawler):
screenshot_tasks = [] # 用于异步分析图片的任务列表 screenshot_tasks = [] # 用于异步分析图片的任务列表
temp_screenshots = [] # 记录临时文件以便后续清理 temp_screenshots = [] # 记录临时文件以便后续清理
logger.info("开始循环截图(UI操作优先,后台并行分析)...") logger.info("[电价页] 开始循环截图(UI操作优先,后台并行分析)...")
try: try:
while price_page_count < max_price_pages: while price_page_count < max_price_pages: