From 8cbcca472b0703e1cabc32bc46c8cc6448a064c2 Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Thu, 15 Jan 2026 11:46:59 +0800 Subject: [PATCH] 'commit' --- Apps/TeLaiDian/Crawler.py | 53 +++++------- Apps/TeLaiDian/Kit.py | 26 ++++++ Apps/TeLaiDian/Template/xczs.jpg | Bin 7794 -> 0 bytes .../__pycache__/Crawler.cpython-310.pyc | Bin 16418 -> 16169 bytes .../TelaiDian/__pycache__/Kit.cpython-310.pyc | Bin 6890 -> 7604 bytes Apps/YeLiTe/Crawler.py | 15 ++-- Apps/YeLiTe/Kit.py | 39 +++++++++ Apps/YeLiTe/ReadImageKit.py | 5 +- Apps/YeLiTe/Service.py | 81 +++++++++++++++++- Apps/YeLiTe/Template/dqdf.jpg | Bin 6814 -> 0 bytes Apps/YeLiTe/Template/nav.jpg | Bin 2935 -> 0 bytes 11 files changed, 178 insertions(+), 41 deletions(-) delete mode 100644 Apps/TeLaiDian/Template/xczs.jpg delete mode 100644 Apps/YeLiTe/Template/dqdf.jpg delete mode 100644 Apps/YeLiTe/Template/nav.jpg diff --git a/Apps/TeLaiDian/Crawler.py b/Apps/TeLaiDian/Crawler.py index 76c54a6..0551c98 100644 --- a/Apps/TeLaiDian/Crawler.py +++ b/Apps/TeLaiDian/Crawler.py @@ -7,7 +7,7 @@ import json import cv2 from Apps.TeLaiDian.Kit import ( take_screenshot, get_image_content_md5, clean_station_name, - setup_logger, read_image, save_image + setup_logger, read_image, save_image, detect_warm_popup_xczs_cv ) from Apps.TeLaiDian.ReadImageKit import ReadImageKit from Apps.TeLaiDian.Service import TeLaiDianService @@ -103,29 +103,18 @@ class TeLaiDianCrawler(BaseCrawler): popup_screen_path = take_screenshot(d, f"tld_detail_popup_{int(time.time())}.jpg") logger.info(f"[详情页] 截图用于检测温馨提示弹窗: {popup_screen_path}") - template_xczs = os.path.join(os.path.dirname(__file__), "Template", "xczs.jpg") - template_point = None - if os.path.exists(template_xczs): - try: - match_res = d.image.match(template_xczs) - if match_res: - if hasattr(match_res, "point") and match_res.point: - template_point = match_res.point - elif isinstance(match_res, dict): - if match_res.get("point"): - template_point = match_res["point"] - elif "x" in match_res and "y" in match_res: - template_point = (match_res["x"], match_res["y"]) - elif isinstance(match_res, (list, tuple)) and len(match_res) >= 2: - template_point = (match_res[0], match_res[1]) - if template_point: - logger.info(f"[详情页] 模板检测到疑似温馨提示弹窗位置: {template_point}") - else: - logger.info("[详情页] 模板未能确定温馨提示弹窗位置") - except Exception as e: - logger.error(f"[详情页] 模板检测温馨提示弹窗失败: {e}") + # 使用 OCR 探测“下次再说”按钮 (替代原来的模板匹配) + ocr_res = detect_warm_popup_xczs_cv(popup_screen_path) + ocr_point = None + if ocr_res: + w, h = d.window_size() + ocr_point = ( + int((ocr_res[0] + ocr_res[2]) / 2 * w / 1000), + int((ocr_res[1] + ocr_res[3]) / 2 * h / 1000) + ) + logger.info(f"[详情页] OCR 检测到“下次再说”按钮位置: {ocr_point}") else: - logger.info(f"[详情页] 温馨提示模板文件不存在: {template_xczs}") + logger.info("[详情页] OCR 未能检测到“下次再说”按钮") vlm_popup = {"has_popup": False} try: @@ -134,10 +123,9 @@ class TeLaiDianCrawler(BaseCrawler): logger.error(f"[详情页] VLM 检测温馨提示弹窗失败: {e}") has_vlm_popup = isinstance(vlm_popup, dict) and vlm_popup.get("has_popup") - if template_point and has_vlm_popup: - click_x = int(template_point[0]) - click_y = int(template_point[1]) - logger.info(f"[详情页] 模板与 VLM 均确认存在温馨提示弹窗,即将点击关闭按钮: ({click_x}, {click_y})") + if ocr_point and has_vlm_popup: + click_x, click_y = ocr_point + logger.info(f"[详情页] OCR 与 VLM 均确认存在温馨提示弹窗,即将点击“下次再说”按钮: ({click_x}, {click_y})") debug_popup_path = popup_screen_path.replace(".jpg", f"_xczs_click_{click_x}_{click_y}.jpg") try: img_popup = read_image(popup_screen_path) @@ -153,7 +141,7 @@ class TeLaiDianCrawler(BaseCrawler): except Exception as e: logger.error(f"[详情页] 点击温馨提示“下次再说”失败: {e}") else: - logger.info(f"[详情页] 温馨提示弹窗未通过双重确认,模板检测: {bool(template_point)} | VLM 检测: {vlm_popup}") + logger.info(f"[详情页] 温馨提示弹窗未通过双重确认,OCR检测: {bool(ocr_point)} | VLM 检测: {vlm_popup}") w, h = d.window_size() logger.info(f"执行显式下拉刷新操作: (x={w//2}, y1={int(h*0.3)} -> y2={int(h*0.8)})") @@ -162,10 +150,11 @@ class TeLaiDianCrawler(BaseCrawler): logger.info(f"等待 {WAIT_AFTER_SCROLL} 秒确保位置校准和列表刷新完成...") await asyncio.sleep(WAIT_AFTER_SCROLL) + max_to_crawl = 1 if FIRST_RUN_ONLY_ONE_STATION else MAX_STATIONS_COUNT processed_count = 0 last_md5 = None - while processed_count < MAX_STATIONS_COUNT: + while processed_count < max_to_crawl: # 1. 截图并分析 screenshot_path = take_screenshot(d, f"tld_list_{int(time.time())}.jpg") @@ -193,7 +182,7 @@ class TeLaiDianCrawler(BaseCrawler): continue for station in stations: - if processed_count >= MAX_STATIONS_COUNT: + if processed_count >= max_to_crawl: break name = station.get("name") @@ -209,7 +198,9 @@ class TeLaiDianCrawler(BaseCrawler): logger.info(f"跳过已处理场站 (Redis): {name}") continue - logger.info(f"处理场站: {name} (坐标: {point}, 距离: {station.get('distance')})") + current_idx = processed_count + 1 + remaining = max_to_crawl - current_idx + logger.info(f"--- [进度: {current_idx}/{max_to_crawl}, 剩余: {remaining}] 处理场站: {name} (坐标: {point}, 距离: {station.get('distance')}) ---") # 点击进入详情 d.click(point[0], point[1]) diff --git a/Apps/TeLaiDian/Kit.py b/Apps/TeLaiDian/Kit.py index bfaa3fe..1f9b767 100644 --- a/Apps/TeLaiDian/Kit.py +++ b/Apps/TeLaiDian/Kit.py @@ -188,6 +188,32 @@ def detect_price_info_container_cv(image_path): return None +def detect_warm_popup_xczs_cv(image_path): + """ + 使用 OCR 精准定位“温馨提示”弹窗中的“下次再说”按钮。 + 返回: [x1, y1, x2, y2] 归一化坐标,如果未找到则返回 None + """ + img = read_image(image_path) + if img is None: + return None + h, w = img.shape[:2] + + keyword = '下次再说' + + try: + reader = get_ocr_reader() + results = reader.read_text(img) + + for (quad, text, prob) in results: + if keyword in text and prob >= 0.5: + res = reader.get_normalized_rect(quad, w, h) + print(f"[OCR识别] 找到“下次再说”: '{text}', 置信度: {prob:.4f}, 归一化坐标: {res}") + return res + except Exception as e: + print(f"OCR 识别发生异常: {e}") + + return None + def setup_logger(name, log_file=None, clear_old_log=False): """ 配置日志,支持同时输出到控制台和文件。 diff --git a/Apps/TeLaiDian/Template/xczs.jpg b/Apps/TeLaiDian/Template/xczs.jpg deleted file mode 100644 index 4ab89644330f9c319a569c9ae1ab6516a24d51c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7794 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 diff --git a/Apps/TelaiDian/__pycache__/Crawler.cpython-310.pyc b/Apps/TelaiDian/__pycache__/Crawler.cpython-310.pyc index ef4f52a50cf6a68d8a379f8536be4e885a7086ee..649b302b56bd3f9472f5bffad981613bfeb24f7d 100644 GIT binary patch delta 4526 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 diff --git a/Apps/TelaiDian/__pycache__/Kit.cpython-310.pyc b/Apps/TelaiDian/__pycache__/Kit.cpython-310.pyc index 710704411402d34c0c2d589f7ab432fd9a76de70..f9ae26bd2137f123b55ffd363ce6e8ad8122ac9c 100644 GIT binary patch delta 2229 zcmZuyU2IcT9Phck?Y(W+uG{$77;{w_qizf^Okpab;J~jf@{x^#x!m>Kb!E4`<@9!A zvvZ3QJ|YO?phl4hi9t~W<9L_|@}N)p!h9JiE`DWP^UE72J@4Z-Wx z6;GmPLZ-T{vn5CpWBP``VRd}3T1)EqIrXCZDP$D!ot}Ag1&}Sx;Mct~gqlv7aogBs zvll=ZQR4|C8MUY(+_r@$vQ=pQBEo8buv~~s{#+-Ty^Nyif&SaGgfx#-dlS;ybs(E` z0<=uZs74U-{)CY#0_az?9rIy!@r&d4m|pa1ryvhhfp(4=4-5QYdCTZPPeoWw>(3)A{7NnUS!1 zW`xwm=G@z7K2kLZ5Bq={1>izD(`+t^myvc}6nt~`7Sz2T{ye4fWU!iS9r-Z$J0W2n zDK)B)AC`pFuvAFhy-@ISKIc>FS4&&S1g|SwGDQ zRfdUU^$1%51f)!-8Xhg2da_TH#SB|ZS}dWP@qUA9QB0|DrC1!A1S>D>W36b7Ibur@ zmH`O0+vw}H7)=X^sZI@s$xmlYJ1yj$8J!9_#jFnD1m?6rYG|+W##wFEJAsU1Io|zY z_2I-?1ON1I{7kS;9+3MR`L*Ee!P;%k0cAiP@MPtz+5?4|^-#In1z*<*IjdxyS?Q#6 zz-zmxE2|!JP&dexV=`5<-eZpA?)M3CWWADuINBT=9Xms94xDGQ!*=&k;u!D|M}Gip zJy{=UOQ_xE*aA8OzIT1787Ppwq}LJlX1?NwN~)i^KJ@wc=;_H*UymO;Jn`j)>qEzL z7k`}i=996}?_EVb4np5NDy7O)N|}k8 z34|oVb_5F{h484hsGx=ob))s_ETN^WR3@eEiuR|qXwPLZN#np#T`G}DDUqcoB*{&@ zBp?MzfXoL<8j}8#)xe!{5UNAc9hM$BIIG)9R`7r4Zg3YSC4Z~@g+Z8=hW&=oW0*pI zwWYaLc%aBqdQ7*Ce4poApOwIALhaI%6oyY4UJlbr8^T{`{q+SlYs0JLCo9H9c$%>V zY}iNmH`-9qi77=<1V>H@7lYKRQ+ikAYliVWwSbtqVWWs@S~0EgP&8H4ZxAZ8EL(#? z6j4wDgiyMse85P;V|njnDcU8Z&IcY%)Ibj)pkN*|*q?l~V%^|D;InN2VTmn58X+vT zw7|bPJhw0m`%!=|qi`iNiBun3i41&X*gMEoH7%(p3{5LME*=!%Fkx7PtPvqUJaCw^ zO$hA(k>btvYjLyT6+PY88fCA?Z5BZpP8Wtv&C&>Y5A(zAKByoN>hlSUW=vxh_I`RH N|7Bi{tX2i){SR7?Vf+99 delta 1658 zcmZWpO>7%Q6wa)Fc5TP86(@wmabl5QLt>INg(@T!NKFDHbxKPVIznlusfC^ z36d1y1WE7Q8cOt$Zqg&BodjKI$@TC2^)tf!HcHE3k@0Yt@So5MQg}+bkD~lgT1~@I zZlqk-^2#S{*e zs&#Y2U(yY6nZFjAM1#9_D2~z@i1Z0?Wyf0Ibg0dq6SG`|4e%S`u?!BcTaIHHST0$n zLrv$HqP_4mn&92?Z$i;Sc|3FEa7ZbcHLR4GWt26YVm_^$8UST(kf@Hz#$br((S#zx zM){}8NO)8XOA_yspXI+RUv7^86BF?ER%)Ixi)C%Kp_!GeW~ddKWmAGGEC|()6}XCB z(=~^_@351C#ENE6vt$v9!;S@d*h`S}Wq?xxazVdppb7_I+YC^C{X;O6`M;4D(d_O> z)R4~1iO4}fK;a+=Bm(eM4#NnfZpp=lp1)kH9JE4cQa~=iU}F>bpRE(`z(w6)$*OI- z0iBw@*a)K~M>Q)#<@3PHjMj9uMA@vE;c!V~rKc~DaHC!|JmX+~DZUc-E)#C(Ma`&S zekYz!9=Q|Og&=Qhs@Jt<1XzIP^)GSwc)*S=Vfb zXpFVPEUekE%?&eZSdFI&9b%o3!pqYGqXB>!NOaT-{Ex&OTH+navz^PwDX%9oZzTIs zVfT9SSA>T7dOOWPJSVwQegaDySHzbQ^xEHCzSmwr6@DT$I#~x3j*Mj=-2Ha%-tGM# zzn;l%1@hD7dP>B{vio;G-}~XC{cG3vZ+>?F*2gp1I=`0c?}tXQ96&(;7A;aq5e{$z zs=0~zFR9)&uv9L_&cG_DJsSte3viVUx_QN7#D=n{gfc9eYS(qg#=-aMD#5`Tv)0{! z2p)0XTd-f|a~*5w;_kVwjR2bBcY4l;eVg-+^xQU9Z0ao22Gw!!jl#kTj)+7xwW2!I zYlqh%mh?1KRg(zg*lwt#TQA5z>)x*Sas$#JwLD7n=2)@ oq&e&?aNrbn5x^7YIq?a|f^d~t!y= 0.5: + pts = np.array(quad).astype(int) + x_min = np.min(pts[:, 0]) + y_min = np.min(pts[:, 1]) + x_max = np.max(pts[:, 0]) + y_max = np.max(pts[:, 1]) + + center_x = (x_min + x_max) // 2 + center_y = (y_min + y_max) // 2 + logger.info(f"[OCR识别] 找到文本: '{text}', 置信度: {prob:.4f}, 中心坐标: ({center_x}, {center_y})") + return (center_x, center_y) + except Exception as e: + logger.error(f"OCR 识别发生异常: {e}") + + return None + def setup_logger(name, log_file=None, clear_old_log=False): """ 配置日志,支持同时输出到控制台和文件。 diff --git a/Apps/YeLiTe/ReadImageKit.py b/Apps/YeLiTe/ReadImageKit.py index 9f2a901..0c51747 100644 --- a/Apps/YeLiTe/ReadImageKit.py +++ b/Apps/YeLiTe/ReadImageKit.py @@ -153,9 +153,10 @@ class ReadImageKit: 每个对象包含: - "name": 场站名称 (仅提取名称文字) - "address": 场站地址 (通常在名称下方,请完整提取地址文字) + - "distance": 距离 (如 "1.2km", "800m" 等,如果存在请提取) - "is_valid": true/false (是否为真实的场站卡片) - 注意:仅提取名称和地址,不要包含距离或价格。 + 注意:仅提取名称、地址和距离,不要包含价格。 """ else: # 如果 CV 没检测到,退回到纯 VLM 模式 @@ -165,6 +166,7 @@ class ReadImageKit: 输出格式为 JSON 数组,每个对象包含: - "name": 场站名称 - "address": 场站地址 (请仔细识别并提取场站的详细地址信息) + - "distance": 距离 (如 "1.2km", "800m" 等,如果存在请提取) - "point": 场站卡片的中心点击坐标 [x, y] - "bbox": 场站卡片的边界框 [x1, y1, x2, y2] """ @@ -187,6 +189,7 @@ class ReadImageKit: final_stations.append({ "name": res.get("name"), "address": res.get("address"), + "distance": res.get("distance"), "point": [(bbox[0] + bbox[2]) // 2, (bbox[1] + bbox[3]) // 2], "bbox": bbox }) diff --git a/Apps/YeLiTe/Service.py b/Apps/YeLiTe/Service.py index 681997c..ffa4d3a 100644 --- a/Apps/YeLiTe/Service.py +++ b/Apps/YeLiTe/Service.py @@ -90,16 +90,71 @@ class YiLaiTeService: except Exception as e: logger.error(f"更新任务结束日志失败: {e}") - async def process_price_detail_data(self, station_name, hourly_schedule, address=None) -> bool: + async def process_price_detail_data(self, station_name, prices, address=None, distance=None) -> bool: """ - 直接保存已处理好的小时段价格数据 + 保存场站数据:名称、地址、24小时价格计划、距离 """ - if not station_name or not hourly_schedule: + if not station_name or not prices: return False station_hash = self.get_hash(station_name) now = datetime.now() + # 1. 预处理价格:生成 24 小时的价格映射 + hourly_schedule = [None] * 24 + + for p in prices: + try: + start_str = p.get('start') or '00:00' + end_str = p.get('end') or '00:00' + + # 解析小时 + start_hour = int(start_str.split(':')[0]) + end_hour = int(end_str.split(':')[0]) + + # 处理 00:00 作为结束时间 + if end_hour == 0 and start_hour != 0: + end_hour = 24 + elif end_hour == 0 and start_hour == 0 and len(prices) == 1: + end_hour = 24 + + # 如果跨天 + if end_hour < start_hour: + end_hour += 24 + + price_val = self._to_float(p.get('price')) + + curr = start_hour + while curr < end_hour: + hour_idx = curr % 24 + hourly_schedule[hour_idx] = { + "start": f"{hour_idx:02d}:00", + "end": f"{(hour_idx + 1):02d}:00", + "price": price_val + } + curr += 1 + except Exception as e: + logger.error(f"解析价格时段失败: {p}, error: {e}") + + # 2. 兜底填充 (补全 24 小时) + last_valid = None + for item in hourly_schedule: + if item: + last_valid = item + break + + if last_valid: + for i in range(24): + if hourly_schedule[i] is None: + new_item = last_valid.copy() + new_item["start"] = f"{i:02d}:00" + new_item["end"] = f"{(i+1):02d}:00" + hourly_schedule[i] = new_item + else: + last_valid = hourly_schedule[i] + else: + logger.warning(f"场站 {station_name} 未能生成有效的 24 小时价格表") + async with await self.db.get_session() as session: # 1. 保存 Profile (如果不存在) profile_id = self.generate_id() @@ -122,7 +177,27 @@ class YiLaiTeService: schedule_json=hourly_schedule, valid_start_time=now ) + + # 3. 保存状态 (记录距离和当前价格) + current_hour = now.hour + current_price_info = hourly_schedule[current_hour] or {} + + status_id = self.generate_id() + await self.station_status_model.save( + session=session, + id=status_id, + station_hash=station_hash, + total_piles=None, + free_piles=None, + piles_detail_json=None, + current_price=current_price_info.get('price'), + distance=distance, + valid_start_time=now + ) + await session.commit() + + logger.info(f"成功保存驿来特场站数据: {station_name} | 距离: {distance} | 价格条数: {len([x for x in hourly_schedule if x])}") return True async def process_station_list_vl(self, image_path, json_metadata, device_info=None, max_count=None) -> list: diff --git a/Apps/YeLiTe/Template/dqdf.jpg b/Apps/YeLiTe/Template/dqdf.jpg deleted file mode 100644 index 424658f0a6adcb327be5c773bdfaa164c4febdcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6814 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 diff --git a/Apps/YeLiTe/Template/nav.jpg b/Apps/YeLiTe/Template/nav.jpg deleted file mode 100644 index 51f123fa211887283e4cb6fd1ecb4c9c81269435..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2935 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