'commit'
This commit is contained in:
@@ -18,3 +18,4 @@ WAIT_AFTER_SCROLL = 2.5
|
|||||||
SAFE_EXCLUDE_RATIO = 0.55 # 大幅增加排除比例,确保从过滤器下方开始识别
|
SAFE_EXCLUDE_RATIO = 0.55 # 大幅增加排除比例,确保从过滤器下方开始识别
|
||||||
BOTTOM_SAFE_EXCLUDE_RATIO = 0.12
|
BOTTOM_SAFE_EXCLUDE_RATIO = 0.12
|
||||||
MIN_CARD_HEIGHT = 250 # 增加最小高度要求,确保卡片信息完整(特来电卡片较长,约300px)
|
MIN_CARD_HEIGHT = 250 # 增加最小高度要求,确保卡片信息完整(特来电卡片较长,约300px)
|
||||||
|
DETAIL_SCROLL_DISTANCE_RATIO = 0.9 # 详情页滑动距离比例,确保露出价格按钮
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from Apps.TeLaiDian.Service import TeLaiDianService
|
|||||||
from Apps.TeLaiDian.Config.Setting import (
|
from Apps.TeLaiDian.Config.Setting import (
|
||||||
SCROLL_DISTANCE_RATIO, WAIT_AFTER_SCROLL, MAX_STATIONS_COUNT,
|
SCROLL_DISTANCE_RATIO, WAIT_AFTER_SCROLL, MAX_STATIONS_COUNT,
|
||||||
SAFE_EXCLUDE_RATIO, BOTTOM_SAFE_EXCLUDE_RATIO, WAIT_DETAIL_PAGE_LOAD,
|
SAFE_EXCLUDE_RATIO, BOTTOM_SAFE_EXCLUDE_RATIO, WAIT_DETAIL_PAGE_LOAD,
|
||||||
WAIT_BACK_TO_LIST
|
WAIT_BACK_TO_LIST, DETAIL_SCROLL_DISTANCE_RATIO
|
||||||
)
|
)
|
||||||
from Core.BaseCrawler import BaseCrawler
|
from Core.BaseCrawler import BaseCrawler
|
||||||
import uiautomator2 as u2
|
import uiautomator2 as u2
|
||||||
@@ -115,9 +115,9 @@ class TeLaiDianCrawler(BaseCrawler):
|
|||||||
logger.info(f"详情页基础信息识别完成: {station_name} | {address}")
|
logger.info(f"详情页基础信息识别完成: {station_name} | {address}")
|
||||||
|
|
||||||
# 2. 向上滑动以露出价格按钮
|
# 2. 向上滑动以露出价格按钮
|
||||||
logger.info("执行滑动操作以显示价格按钮...")
|
logger.info(f"执行滑动操作以显示价格按钮 (距离比例: {DETAIL_SCROLL_DISTANCE_RATIO})...")
|
||||||
# 从屏幕中间向上滑动,scale=0.6 表示滑动距离约为屏幕高度的 60%
|
# 从屏幕中间向上滑动
|
||||||
d.swipe_ext("up", scale=0.6)
|
d.swipe_ext("up", scale=DETAIL_SCROLL_DISTANCE_RATIO)
|
||||||
await asyncio.sleep(1.5)
|
await asyncio.sleep(1.5)
|
||||||
|
|
||||||
# 3. 点击“价格信息”按钮 (jgxx.jpg)
|
# 3. 点击“价格信息”按钮 (jgxx.jpg)
|
||||||
|
|||||||
97
Apps/TeLaiDian/TestDetailCV.py
Normal file
97
Apps/TeLaiDian/TestDetailCV.py
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# 将项目根目录添加到 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)
|
||||||
|
|
||||||
|
from Apps.TeLaiDian import Kit
|
||||||
|
|
||||||
|
def detect_price_areas_cv(image_path):
|
||||||
|
"""
|
||||||
|
专门用于详情页识别价格点击区域的测试函数
|
||||||
|
"""
|
||||||
|
img = Kit.read_image(image_path)
|
||||||
|
if img is None:
|
||||||
|
print("错误: 无法读取图片")
|
||||||
|
return []
|
||||||
|
|
||||||
|
h, w = img.shape[:2]
|
||||||
|
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||||
|
|
||||||
|
# 1. 转换为 HSV 空间,方便寻找橘红色价格
|
||||||
|
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
||||||
|
|
||||||
|
# 橘红色的 HSV 范围 (大致)
|
||||||
|
lower_orange = np.array([0, 150, 150])
|
||||||
|
upper_orange = np.array([20, 255, 255])
|
||||||
|
mask = cv2.inRange(hsv, lower_orange, upper_orange)
|
||||||
|
|
||||||
|
# 2. 对掩码进行膨胀,连接数字
|
||||||
|
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 20))
|
||||||
|
dilated = cv2.dilate(mask, kernel)
|
||||||
|
|
||||||
|
# 3. 寻找轮廓
|
||||||
|
contours, _ = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||||||
|
|
||||||
|
detected_areas = []
|
||||||
|
|
||||||
|
for cnt in contours:
|
||||||
|
x, y, cw, ch = cv2.boundingRect(cnt)
|
||||||
|
|
||||||
|
# 橘红色价格通常在屏幕上半部,且宽度适中
|
||||||
|
if 150 < y < h * 0.6 and cw > 100:
|
||||||
|
# 我们找到了价格数字。用户说要点击的是这个区域。
|
||||||
|
# 我们可以适当扩大这个区域,或者直接取其中心。
|
||||||
|
padding = 20
|
||||||
|
detected_areas.append([
|
||||||
|
max(0, x - padding),
|
||||||
|
max(0, y - padding),
|
||||||
|
min(w, x + cw + padding),
|
||||||
|
min(h, y + ch + padding)
|
||||||
|
])
|
||||||
|
|
||||||
|
# 按 X 轴排序,找到最左边的价格
|
||||||
|
detected_areas.sort(key=lambda b: b[0])
|
||||||
|
return detected_areas
|
||||||
|
|
||||||
|
def run_test(image_path):
|
||||||
|
print(f"分析图片: {image_path}")
|
||||||
|
|
||||||
|
# 获取所有可能的区域
|
||||||
|
bboxes = detect_price_areas_cv(image_path)
|
||||||
|
print(f"检测到 {len(bboxes)} 个潜在区域:")
|
||||||
|
for i, box in enumerate(bboxes):
|
||||||
|
print(f" 区域 {i}: {box} (w={box[2]-box[0]}, h={box[3]-box[1]})")
|
||||||
|
|
||||||
|
# 生成 _vl.jpg (仅框)
|
||||||
|
vl_path = image_path.replace(".jpg", "_vl.jpg")
|
||||||
|
img_vl = Kit.read_image(image_path)
|
||||||
|
for i, box in enumerate(bboxes):
|
||||||
|
cv2.rectangle(img_vl, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 2)
|
||||||
|
cv2.putText(img_vl, str(i), (box[0], box[1]-5), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
|
||||||
|
Kit.save_image(vl_path, img_vl)
|
||||||
|
print(f"已生成标注图: {vl_path}")
|
||||||
|
|
||||||
|
# 生成 _flag.jpg (框 + 中心点)
|
||||||
|
flag_path = image_path.replace(".jpg", "_flag.jpg")
|
||||||
|
img_flag = Kit.read_image(image_path)
|
||||||
|
for i, box in enumerate(bboxes):
|
||||||
|
cv2.rectangle(img_flag, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 2)
|
||||||
|
center_x = (box[0] + box[2]) // 2
|
||||||
|
center_y = (box[1] + box[3]) // 2
|
||||||
|
cv2.circle(img_flag, (center_x, center_y), 10, (0, 0, 255), -1)
|
||||||
|
cv2.putText(img_flag, f"P{i}", (box[0], box[1]-5), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
|
||||||
|
Kit.save_image(flag_path, img_flag)
|
||||||
|
print(f"已生成人工核对图: {flag_path}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_image = r"d:\dsWork\aiData\Output\Screenshot_20260114_075758.jpg"
|
||||||
|
if os.path.exists(test_image):
|
||||||
|
run_test(test_image)
|
||||||
|
else:
|
||||||
|
print(f"错误: 找不到测试图片 {test_image}")
|
||||||
Reference in New Issue
Block a user