'commit'
This commit is contained in:
@@ -63,6 +63,12 @@ class TeLaiDianCrawler(BaseCrawler):
|
||||
target_x = int(close_point[0] * w / 1000)
|
||||
target_y = int(close_point[1] * h / 1000)
|
||||
|
||||
# 安全校验:绝对不能点击微信小程序的胶囊按钮区 (右上角)
|
||||
# 胶囊按钮通常在 x > 80% 宽度 且 y < 100 像素(或 8% 高度) 的区域
|
||||
if target_x > w * 0.75 and target_y < 150:
|
||||
logger.warning(f"⚠️ 拒绝点击疑似微信胶囊按钮的区域: ({target_x}, {target_y})")
|
||||
continue
|
||||
|
||||
logger.info(f"第 {i+1} 轮发现广告: {res.get('reason')},点击关闭: ({target_x}, {target_y})")
|
||||
d.click(target_x, target_y)
|
||||
await asyncio.sleep(1.5)
|
||||
@@ -77,8 +83,15 @@ class TeLaiDianCrawler(BaseCrawler):
|
||||
# 进入列表页先清理广告
|
||||
await self.clear_ads(d)
|
||||
|
||||
# [优化] 向下滚动以刷新/校准地理位置
|
||||
logger.info("执行下拉操作以刷新校准地理位置...")
|
||||
d.swipe_ext("down", scale=0.6)
|
||||
logger.info("等待 2 秒让位置校准生效...")
|
||||
await asyncio.sleep(2.0)
|
||||
|
||||
processed_count = 0
|
||||
last_md5 = None
|
||||
processed_station_names = set() # 用于列表级去重
|
||||
|
||||
while processed_count < MAX_STATIONS_COUNT:
|
||||
# 1. 截图并分析
|
||||
@@ -94,6 +107,14 @@ class TeLaiDianCrawler(BaseCrawler):
|
||||
|
||||
stations = await self.read_image_kit.analyze_station_list(screenshot_path)
|
||||
if not stations:
|
||||
# 检查是否意外退出了小程序
|
||||
is_wrong_page = await self.check_wrong_page(d, screenshot_path)
|
||||
if is_wrong_page:
|
||||
logger.error("检测到已退出详情列表页(可能回到了搜索页),尝试重新进入...")
|
||||
await self.open_app()
|
||||
await asyncio.sleep(5)
|
||||
continue
|
||||
|
||||
logger.info("本页未检测到场站,尝试滑动...")
|
||||
d.swipe_ext("up", scale=SCROLL_DISTANCE_RATIO)
|
||||
await asyncio.sleep(WAIT_AFTER_SCROLL)
|
||||
@@ -109,6 +130,10 @@ class TeLaiDianCrawler(BaseCrawler):
|
||||
if not name or not point:
|
||||
continue
|
||||
|
||||
if name in processed_station_names:
|
||||
logger.info(f"跳过已处理场站: {name}")
|
||||
continue
|
||||
|
||||
logger.info(f"处理场站: {name} (坐标: {point})")
|
||||
|
||||
# 点击进入详情
|
||||
@@ -116,21 +141,25 @@ class TeLaiDianCrawler(BaseCrawler):
|
||||
logger.info(f"已点击场站 '{name}',等待 {WAIT_DETAIL_PAGE_LOAD}s 加载详情页...")
|
||||
await asyncio.sleep(WAIT_DETAIL_PAGE_LOAD)
|
||||
|
||||
# 截图验证是否进入详情页 (可选:可以加入更复杂的页面特征判断)
|
||||
# 截图验证是否进入详情页
|
||||
detail_check_path = take_screenshot(d, f"tld_detail_check_{int(time.time())}.jpg")
|
||||
logger.info(f"详情页快照已保存: {detail_check_path}")
|
||||
|
||||
# 简单验证:如果标题包含 "我的卡券"、"优惠券" 等,说明点错了
|
||||
# 简单验证:如果标题包含 "我的卡券"、"优惠券"、"新人福利" 等,说明点错了
|
||||
is_wrong_page = await self.check_wrong_page(d, detail_check_path)
|
||||
if is_wrong_page:
|
||||
logger.warning(f"检测到进入了错误页面,尝试返回列表...")
|
||||
# 尝试点击左上角的返回箭头,如果没有,则执行系统 back
|
||||
d.click(40, 70) # 特来电通常左上角有返回箭头
|
||||
await asyncio.sleep(1.0)
|
||||
d.press("back")
|
||||
await asyncio.sleep(WAIT_BACK_TO_LIST)
|
||||
if os.path.exists(detail_check_path): os.remove(detail_check_path)
|
||||
continue
|
||||
|
||||
|
||||
# 爬取详情
|
||||
await self.crawl_detail_logic(d, station)
|
||||
processed_station_names.add(name)
|
||||
|
||||
# 返回列表
|
||||
d.press("back")
|
||||
@@ -149,26 +178,11 @@ class TeLaiDianCrawler(BaseCrawler):
|
||||
"""
|
||||
检查是否误触进入了错误的页面(如:我的卡券、活动页等)
|
||||
"""
|
||||
prompt = """
|
||||
分析这张截图,判断这是否是一个“充电站详情页”。
|
||||
特征:详情页通常包含场站名称、电价列表、电桩状态等。
|
||||
如果页面显示的是“我的卡券”、“优惠券”、“个人中心”或“活动广告”,则不是详情页。
|
||||
|
||||
输出格式为 JSON:
|
||||
{
|
||||
"is_detail_page": true/false,
|
||||
"page_type": "detail" / "coupons" / "ad" / "other",
|
||||
"reason": "判断依据"
|
||||
}
|
||||
"""
|
||||
try:
|
||||
res_text = await self.read_image_kit.vlm.analyze_image(image_path, prompt)
|
||||
json_str = self.read_image_kit.vlm.extract_json(res_text)
|
||||
data = json.loads(json_str)
|
||||
return not data.get("is_detail_page", True)
|
||||
except Exception as e:
|
||||
logger.error(f"检查页面类型失败: {e}")
|
||||
return False
|
||||
data = await self.read_image_kit.check_wrong_page_vlm(image_path)
|
||||
is_detail = data.get("is_detail_page", True)
|
||||
if not is_detail:
|
||||
logger.warning(f"⚠️ 确认进入错误页面: {data.get('page_type')} ({data.get('reason')})")
|
||||
return not is_detail
|
||||
|
||||
async def crawl_detail_logic(self, d, station_info):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user