|
@@ -45,7 +45,7 @@ ROW_REST_MAX = 17 # 50条整点休息最长分钟数
|
|
|
|
|
|
|
|
# 进入商品页unknown(页面没加载出来)时的处理:
|
|
# 进入商品页unknown(页面没加载出来)时的处理:
|
|
|
# 每确认一次unknown → back一层+重新点击进入;累计UNKNOWN_REENTER_LIMIT次加载全失败 → 跳过本商品
|
|
# 每确认一次unknown → back一层+重新点击进入;累计UNKNOWN_REENTER_LIMIT次加载全失败 → 跳过本商品
|
|
|
-# 连续2个商品都这样 → step3白屏分级恢复:冷却×2轮 → 重启App(最多MAX_WHITE_RESTART次)→ 超限回告调度重派
|
|
|
|
|
|
|
+# 连续2个商品都这样 → step3白屏恢复:关App休息60~120s → 重启App(最多MAX_WHITE_RESTART次)→ 超限回告调度重派
|
|
|
UNKNOWN_REENTER_LIMIT = 5
|
|
UNKNOWN_REENTER_LIMIT = 5
|
|
|
MAX_WHITE_RESTART = 3 # 白屏重启恢复上限(超过→置重派标志,回告调度换设备,不终止任务数据)
|
|
MAX_WHITE_RESTART = 3 # 白屏重启恢复上限(超过→置重派标志,回告调度换设备,不终止任务数据)
|
|
|
WHITE_SUCCESS_RESET_N = 5 # 连续成功采N个商品后清零白屏重启计数(额度恢复)
|
|
WHITE_SUCCESS_RESET_N = 5 # 连续成功采N个商品后清零白屏重启计数(额度恢复)
|
|
@@ -154,6 +154,18 @@ def _shot_path(ex: SafeExecutor, name: str) -> str:
|
|
|
return str(d / name)
|
|
return str(d / name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def _save_evidence(shot: str, tag: str):
|
|
|
|
|
+ """决策留档: 触发重启/放弃时刻的截图另存时间戳副本。
|
|
|
|
|
+ page_check/detail_check 同一家店内会被下一轮覆盖,
|
|
|
|
|
+ 留档(时间戳+原因标签)便于事后人工核对AI是否误判。"""
|
|
|
|
|
+ try:
|
|
|
|
|
+ if shot and os.path.exists(shot):
|
|
|
|
|
+ ts = time.strftime("%Y%m%d_%H%M%S")
|
|
|
|
|
+ shutil.copy2(shot, str(Path(shot).parent / f"{ts}_{tag}.png"))
|
|
|
|
|
+ except Exception:
|
|
|
|
|
+ pass
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def _screenshot(ex: SafeExecutor, name: str) -> str:
|
|
def _screenshot(ex: SafeExecutor, name: str) -> str:
|
|
|
import os
|
|
import os
|
|
|
# 按 设备ID/步骤 隔离截图(目录已含设备ID,文件名不再加设备前缀)
|
|
# 按 设备ID/步骤 隔离截图(目录已含设备ID,文件名不再加设备前缀)
|
|
@@ -990,13 +1002,16 @@ def _adb_swipe_left(ex: SafeExecutor, y_ratio: float = 0.3):
|
|
|
w, h = ex.driver.window_size()
|
|
w, h = ex.driver.window_size()
|
|
|
distance = int(w * _random.uniform(0.55, 0.68))
|
|
distance = int(w * _random.uniform(0.55, 0.68))
|
|
|
try:
|
|
try:
|
|
|
- pts = wrist_arc_pts_h(w, h, distance, y_ratio=y_ratio, n=60, drift_range=(30, 70))
|
|
|
|
|
- if touchpipe_drag(ex.driver, pts):
|
|
|
|
|
|
|
+ pts = wrist_arc_pts_h(w, h, distance, y_ratio=y_ratio, n=30, drift_range=(30, 70))
|
|
|
|
|
+ # 真人轻扫~0.2s: 点数减半 + 步进/停顿收紧, 整笔含down/up往返~0.25s完成
|
|
|
|
|
+ if touchpipe_drag(ex.driver, pts, step=_random.uniform(0.003, 0.005),
|
|
|
|
|
+ hold=_random.uniform(0.02, 0.05),
|
|
|
|
|
+ tail=_random.uniform(0.015, 0.04)):
|
|
|
human_sleep(1.2)
|
|
human_sleep(1.2)
|
|
|
return
|
|
return
|
|
|
print(" [图片左滑] TouchPipe未生效,降级motionevent")
|
|
print(" [图片左滑] TouchPipe未生效,降级motionevent")
|
|
|
pts10 = wrist_arc_pts_h(w, h, distance, y_ratio=y_ratio, n=10, drift_range=(30, 70))
|
|
pts10 = wrist_arc_pts_h(w, h, distance, y_ratio=y_ratio, n=10, drift_range=(30, 70))
|
|
|
- motionevent_drag(ex.device_id, pts10)
|
|
|
|
|
|
|
+ motionevent_drag(ex.device_id, pts10, step=_random.uniform(0.015, 0.022))
|
|
|
human_sleep(1.2)
|
|
human_sleep(1.2)
|
|
|
return
|
|
return
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
@@ -1032,6 +1047,57 @@ def _adb_swipe_up_short(ex: SafeExecutor):
|
|
|
)
|
|
)
|
|
|
human_sleep(1)
|
|
human_sleep(1)
|
|
|
|
|
|
|
|
|
|
+# ── 店铺反馈弹窗(滑动被误判长按店铺名)检测与关闭 ──
|
|
|
|
|
+FEEDBACK_POPUP_KW = ("店铺问题", "不喜欢该店铺", "与搜索词无关",
|
|
|
|
|
+ "图片不够真实", "商品品质不好", "价格太贵", "疑似情色")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def _close_feedback_popup(ex: SafeExecutor) -> bool:
|
|
|
|
|
+ """检测并关闭"店铺问题/商品问题"反馈弹窗(滑动被误判长按所致)。
|
|
|
|
|
+ 关闭方式: 点弹窗上方暗区,或右上角×(back 会退回搜索页,不能用)。
|
|
|
|
|
+ 返回 True=检测到弹窗(无论是否成功关闭), False=没弹窗。"""
|
|
|
|
|
+ try:
|
|
|
|
|
+ shot = _shot_path(ex, "ad_feedback_popup.png")
|
|
|
|
|
+ ex.driver.screenshot(shot)
|
|
|
|
|
+ blocks = OCR.recognize(shot, detail="all")
|
|
|
|
|
+ texts = [b.get("text", "") for b in blocks]
|
|
|
|
|
+ if not any(kw in t for t in texts for kw in FEEDBACK_POPUP_KW):
|
|
|
|
|
+ return False
|
|
|
|
|
+ print("[step3] 检测到店铺反馈弹窗(滑动误触长按),关闭中")
|
|
|
|
|
+ w, h = ex.driver.window_size()
|
|
|
|
|
+ anchor_y = 0
|
|
|
|
|
+ for b in blocks:
|
|
|
|
|
+ if "店铺问题" in b.get("text", ""):
|
|
|
|
|
+ anchor_y = (b["box"][1] + b["box"][3]) // 2
|
|
|
|
|
+ break
|
|
|
|
|
+ # 1) 点弹窗上方暗区(大目标); 2) 点×(与"店铺问题"同行右侧); 3) ×实测兜底位
|
|
|
|
|
+ taps = [(int(w * 0.5), int(h * 0.25))]
|
|
|
|
|
+ if anchor_y:
|
|
|
|
|
+ taps.append((int(w * 0.84), anchor_y))
|
|
|
|
|
+ taps.append((int(w * 0.84), int(h * 0.52)))
|
|
|
|
|
+ for tx, ty in taps:
|
|
|
|
|
+ ex.tap(tx, ty)
|
|
|
|
|
+ time.sleep(1.2)
|
|
|
|
|
+ ex.driver.screenshot(shot)
|
|
|
|
|
+ blocks = OCR.recognize(shot, detail="all")
|
|
|
|
|
+ texts = [b.get("text", "") for b in blocks]
|
|
|
|
|
+ if not any(kw in t for t in texts for kw in FEEDBACK_POPUP_KW):
|
|
|
|
|
+ print("[step3] 反馈弹窗已关闭")
|
|
|
|
|
+ return True
|
|
|
|
|
+ print("[step3] 反馈弹窗关闭未生效,后续批次可能空转")
|
|
|
|
|
+ return True
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+ print(f"[step3] 反馈弹窗检测异常: {e}")
|
|
|
|
|
+ return False
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def _swipe_next_batch(ex: SafeExecutor, distance: int):
|
|
|
|
|
+ """列表上滑统一入口: 滑动后检查长按误触的反馈弹窗。
|
|
|
|
|
+ 弹窗会骗过滑动的像素diff验证且挡住列表(后续批次全是旧卡片) → 关掉后补滑一次。"""
|
|
|
|
|
+ _adb_swipe_up(ex, distance)
|
|
|
|
|
+ if _close_feedback_popup(ex):
|
|
|
|
|
+ _adb_swipe_up(ex, distance)
|
|
|
|
|
+
|
|
|
|
|
|
|
|
def _find_close_btn(shot_path: str) -> Optional[dict]:
|
|
def _find_close_btn(shot_path: str) -> Optional[dict]:
|
|
|
"""
|
|
"""
|
|
@@ -1877,6 +1943,7 @@ def step4_parse_qr(ex: SafeExecutor, product_title: str, shop_name: str = "",
|
|
|
confirm_raw = OCR.recognize(shot_check, detail="all")
|
|
confirm_raw = OCR.recognize(shot_check, detail="all")
|
|
|
ptype2 = AIParser().check_page(confirm_raw).get("type", "unknown")
|
|
ptype2 = AIParser().check_page(confirm_raw).get("type", "unknown")
|
|
|
if ptype2 == "home":
|
|
if ptype2 == "home":
|
|
|
|
|
+ _save_evidence(shot_check, "restart_home1")
|
|
|
print(" ⚠ 二次确认仍为首页(被踢回/退过头),触发重启恢复")
|
|
print(" ⚠ 二次确认仍为首页(被踢回/退过头),触发重启恢复")
|
|
|
return "__RESTART__"
|
|
return "__RESTART__"
|
|
|
if ptype2 == "normal":
|
|
if ptype2 == "normal":
|
|
@@ -1931,6 +1998,7 @@ def step4_parse_qr(ex: SafeExecutor, product_title: str, shop_name: str = "",
|
|
|
continue
|
|
continue
|
|
|
return "__TERMINATE__"
|
|
return "__TERMINATE__"
|
|
|
if ptype2 == "home":
|
|
if ptype2 == "home":
|
|
|
|
|
+ _save_evidence(shot_check, "restart_home2")
|
|
|
print(" ⚠ 二次确认检测到首页,触发重启恢复")
|
|
print(" ⚠ 二次确认检测到首页,触发重启恢复")
|
|
|
return "__RESTART__"
|
|
return "__RESTART__"
|
|
|
if ptype2 == "list":
|
|
if ptype2 == "list":
|
|
@@ -2062,6 +2130,7 @@ def step4_parse_qr(ex: SafeExecutor, product_title: str, shop_name: str = "",
|
|
|
human_sleep(3) # 点击后先等页面响应(验证码处理后/网络慢时切换慢)
|
|
human_sleep(3) # 点击后先等页面响应(验证码处理后/网络慢时切换慢)
|
|
|
|
|
|
|
|
# 检测是否进入商品详情页(验证码检测优先——验证码页文字块少,不能被"加载中"分支挡掉)
|
|
# 检测是否进入商品详情页(验证码检测优先——验证码页文字块少,不能被"加载中"分支挡掉)
|
|
|
|
|
+ notready_streak = 0 # 连续"未就绪"轮次(白屏时OCR只剩状态栏1~3块文字)
|
|
|
for _ in range(8):
|
|
for _ in range(8):
|
|
|
human_sleep(2)
|
|
human_sleep(2)
|
|
|
detail_check = _pfx("detail_check.png")
|
|
detail_check = _pfx("detail_check.png")
|
|
@@ -2092,12 +2161,21 @@ def step4_parse_qr(ex: SafeExecutor, product_title: str, shop_name: str = "",
|
|
|
|
|
|
|
|
# 2. 页面加载中/切换中(文字少且无验证码)→ 继续等待,不误判
|
|
# 2. 页面加载中/切换中(文字少且无验证码)→ 继续等待,不误判
|
|
|
if len(detail_texts) <= 8:
|
|
if len(detail_texts) <= 8:
|
|
|
|
|
+ notready_streak += 1
|
|
|
|
|
+ # 连续3轮仅状态栏级文字 → 大概率白屏(有图无字),立即跳过别盲等
|
|
|
|
|
+ # (原逻辑只会"继续等待",3次尝试×8轮能空转1分半)
|
|
|
|
|
+ if notready_streak >= 3 and _is_white_screen(detail_check):
|
|
|
|
|
+ _save_evidence(detail_check, "white_skip_detail")
|
|
|
|
|
+ _LAST_SKIP_WHITE = True
|
|
|
|
|
+ print(" ⚠ 详情页白屏(连续多轮仅状态栏文字),跳过本商品")
|
|
|
|
|
+ return "__SKIP__"
|
|
|
print(f" 页面未就绪(仅{len(detail_texts)}块文字),继续等待...")
|
|
print(f" 页面未就绪(仅{len(detail_texts)}块文字),继续等待...")
|
|
|
continue
|
|
continue
|
|
|
|
|
|
|
|
# 2.5 检测是否退回首页/列表页(点标题失败/back过头时常见)→ 立即处理,不盲等
|
|
# 2.5 检测是否退回首页/列表页(点标题失败/back过头时常见)→ 立即处理,不盲等
|
|
|
joined_texts = "".join(detail_texts)
|
|
joined_texts = "".join(detail_texts)
|
|
|
if ("看病买药" in joined_texts) and ("我的" in joined_texts):
|
|
if ("看病买药" in joined_texts) and ("我的" in joined_texts):
|
|
|
|
|
+ _save_evidence(detail_check, "restart_home_kw")
|
|
|
print(" ⚠ 检测到已退回首页,触发重启恢复")
|
|
print(" ⚠ 检测到已退回首页,触发重启恢复")
|
|
|
return "__RESTART__"
|
|
return "__RESTART__"
|
|
|
if "筛选" in joined_texts:
|
|
if "筛选" in joined_texts:
|
|
@@ -2136,6 +2214,7 @@ def step4_parse_qr(ex: SafeExecutor, product_title: str, shop_name: str = "",
|
|
|
continue
|
|
continue
|
|
|
return "__TERMINATE__"
|
|
return "__TERMINATE__"
|
|
|
if ai_page.get("type") == "home":
|
|
if ai_page.get("type") == "home":
|
|
|
|
|
+ _save_evidence(last_shot, "restart_home_ai")
|
|
|
print(" ⚠ AI检测到首页,触发重启恢复")
|
|
print(" ⚠ AI检测到首页,触发重启恢复")
|
|
|
return "__RESTART__"
|
|
return "__RESTART__"
|
|
|
if ai_page.get("type") == "list":
|
|
if ai_page.get("type") == "list":
|
|
@@ -2539,7 +2618,7 @@ def _recover_to_list(ex: SafeExecutor, brand_keyword: str,
|
|
|
remain = total_scroll_px
|
|
remain = total_scroll_px
|
|
|
while remain > 0:
|
|
while remain > 0:
|
|
|
step = min(remain, int(h * 0.5))
|
|
step = min(remain, int(h * 0.5))
|
|
|
- _adb_swipe_up(ex, step)
|
|
|
|
|
|
|
+ _swipe_next_batch(ex, step)
|
|
|
remain -= step
|
|
remain -= step
|
|
|
human_sleep(2)
|
|
human_sleep(2)
|
|
|
|
|
|
|
@@ -2640,7 +2719,7 @@ def step3_swipe_and_enter(ex: SafeExecutor, keyword: str, brand: str = "", task:
|
|
|
if start_page > 0:
|
|
if start_page > 0:
|
|
|
print(f"[step3] 跨设备接力恢复: 调度页码={start_page},滑动{start_page}页...")
|
|
print(f"[step3] 跨设备接力恢复: 调度页码={start_page},滑动{start_page}页...")
|
|
|
for i in range(start_page):
|
|
for i in range(start_page):
|
|
|
- _adb_swipe_up(ex, int(h * 0.7))
|
|
|
|
|
|
|
+ _swipe_next_batch(ex, int(h * 0.7))
|
|
|
human_sleep(2)
|
|
human_sleep(2)
|
|
|
elif progress:
|
|
elif progress:
|
|
|
visited = set(progress.get("visited") or [])
|
|
visited = set(progress.get("visited") or [])
|
|
@@ -2649,13 +2728,12 @@ def step3_swipe_and_enter(ex: SafeExecutor, keyword: str, brand: str = "", task:
|
|
|
remain = total_scroll_px
|
|
remain = total_scroll_px
|
|
|
while remain > 0:
|
|
while remain > 0:
|
|
|
step = min(remain, int(h * 0.5))
|
|
step = min(remain, int(h * 0.5))
|
|
|
- _adb_swipe_up(ex, step)
|
|
|
|
|
|
|
+ _swipe_next_batch(ex, step)
|
|
|
remain -= step
|
|
remain -= step
|
|
|
human_sleep(2)
|
|
human_sleep(2)
|
|
|
else:
|
|
else:
|
|
|
visited = set()
|
|
visited = set()
|
|
|
|
|
|
|
|
- white_fail_round = 0 # 白屏分级恢复轮次(冷却→冷却→重启;采到正常商品清零)
|
|
|
|
|
white_restart_count = 0 # 白屏重启恢复累计(>=MAX_WHITE_RESTART → 置重派标志)
|
|
white_restart_count = 0 # 白屏重启恢复累计(>=MAX_WHITE_RESTART → 置重派标志)
|
|
|
ws_success_count = 0 # 连续成功采集计数(>=WHITE_SUCCESS_RESET_N → 白屏重启额度清零)
|
|
ws_success_count = 0 # 连续成功采集计数(>=WHITE_SUCCESS_RESET_N → 白屏重启额度清零)
|
|
|
unknown_skip_streak = 0 # 连续"进页失败跳过"计数(跨批次,采到正常商品清零;连续2→分级恢复)
|
|
unknown_skip_streak = 0 # 连续"进页失败跳过"计数(跨批次,采到正常商品清零;连续2→分级恢复)
|
|
@@ -2792,7 +2870,7 @@ def step3_swipe_and_enter(ex: SafeExecutor, keyword: str, brand: str = "", task:
|
|
|
swipe_dist = max(target_y - int(h * 0.15), int(h * 0.15))
|
|
swipe_dist = max(target_y - int(h * 0.15), int(h * 0.15))
|
|
|
else:
|
|
else:
|
|
|
swipe_dist = int(h * 0.3)
|
|
swipe_dist = int(h * 0.3)
|
|
|
- _adb_swipe_up(ex, swipe_dist)
|
|
|
|
|
|
|
+ _swipe_next_batch(ex, swipe_dist)
|
|
|
total_scroll_px += swipe_dist
|
|
total_scroll_px += swipe_dist
|
|
|
human_sleep(1.1) # 滑动后停顿 0.8~1.4s(±30%抖动)
|
|
human_sleep(1.1) # 滑动后停顿 0.8~1.4s(±30%抖动)
|
|
|
batch_no += 1
|
|
batch_no += 1
|
|
@@ -2824,7 +2902,6 @@ def step3_swipe_and_enter(ex: SafeExecutor, keyword: str, brand: str = "", task:
|
|
|
continue
|
|
continue
|
|
|
if result:
|
|
if result:
|
|
|
unknown_skip_streak = 0 # 采到一个正常商品就清零
|
|
unknown_skip_streak = 0 # 采到一个正常商品就清零
|
|
|
- white_fail_round = 0 # 白屏分级轮次也清零
|
|
|
|
|
ws_success_count += 1
|
|
ws_success_count += 1
|
|
|
if ws_success_count >= WHITE_SUCCESS_RESET_N:
|
|
if ws_success_count >= WHITE_SUCCESS_RESET_N:
|
|
|
if white_restart_count > 0:
|
|
if white_restart_count > 0:
|
|
@@ -2847,34 +2924,33 @@ def step3_swipe_and_enter(ex: SafeExecutor, keyword: str, brand: str = "", task:
|
|
|
break
|
|
break
|
|
|
|
|
|
|
|
if ws_recover_requested:
|
|
if ws_recover_requested:
|
|
|
- # 白屏分级恢复:连续2商品进页失败 → 冷却×2轮(不重启) → 重启App → 超限置重派标志
|
|
|
|
|
- white_fail_round += 1
|
|
|
|
|
- import random as _random
|
|
|
|
|
- if white_fail_round <= 2:
|
|
|
|
|
- _cd = _random.uniform(180, 300) if white_fail_round == 1 else _random.uniform(300, 480)
|
|
|
|
|
- print(f"[step3] 连续{unknown_skip_streak}个商品进页失败,冷却{_cd:.0f}秒"
|
|
|
|
|
- f"(分级恢复第{white_fail_round}/2轮,不重启)...")
|
|
|
|
|
- if not _chunked_sleep_with_report(_cd, "白屏冷却"):
|
|
|
|
|
- stopped = True
|
|
|
|
|
- break
|
|
|
|
|
- unknown_skip_streak = 0
|
|
|
|
|
- continue
|
|
|
|
|
|
|
+ # 白屏恢复:冷却等待无效 → 直接关App → 休息60~120s → 重启重搜滑回(超限回告调度重派)
|
|
|
white_restart_count += 1
|
|
white_restart_count += 1
|
|
|
if white_restart_count >= MAX_WHITE_RESTART:
|
|
if white_restart_count >= MAX_WHITE_RESTART:
|
|
|
WHITE_SCREEN_REASSIGN = True
|
|
WHITE_SCREEN_REASSIGN = True
|
|
|
- WHITE_SCREEN_REASSIGN_REASON = f"商品页反复白屏,重启恢复{white_restart_count}次无效"
|
|
|
|
|
|
|
+ WHITE_SCREEN_REASSIGN_REASON = f"商品页反复白屏,关App重启恢复{white_restart_count}次无效"
|
|
|
print(f"[step3] 白屏重启恢复超限({MAX_WHITE_RESTART}次),置重派标志,停止采集(进度保留)")
|
|
print(f"[step3] 白屏重启恢复超限({MAX_WHITE_RESTART}次),置重派标志,停止采集(进度保留)")
|
|
|
stopped = True
|
|
stopped = True
|
|
|
break
|
|
break
|
|
|
- print(f"[step3] 白屏反复出现,重启App恢复(第{white_restart_count}/{MAX_WHITE_RESTART}次)")
|
|
|
|
|
|
|
+ print(f"[step3] 检测到白屏,关App休息后重启(第{white_restart_count}/{MAX_WHITE_RESTART}次)")
|
|
|
_save_progress(ex.device_id, keyword, visited, total_scroll_px, batch_no)
|
|
_save_progress(ex.device_id, keyword, visited, total_scroll_px, batch_no)
|
|
|
|
|
+ try:
|
|
|
|
|
+ ex.driver.app_stop(APP_PACKAGE) # 先把App彻底关掉再休息
|
|
|
|
|
+ except Exception as _e:
|
|
|
|
|
+ print(f" 关App失败(不影响流程): {_e}")
|
|
|
|
|
+ import random as _random
|
|
|
|
|
+ _rest = _random.uniform(60, 120)
|
|
|
|
|
+ print(f" 休息{_rest:.0f}秒...")
|
|
|
|
|
+ if not _chunked_sleep_with_report(_rest, "白屏重启"):
|
|
|
|
|
+ stopped = True
|
|
|
|
|
+ break
|
|
|
step1_open_app(ex)
|
|
step1_open_app(ex)
|
|
|
step2_search(ex, (brand + keyword).strip() or keyword)
|
|
step2_search(ex, (brand + keyword).strip() or keyword)
|
|
|
# 从列表顶部滑动恢复到上次位置
|
|
# 从列表顶部滑动恢复到上次位置
|
|
|
remain = total_scroll_px
|
|
remain = total_scroll_px
|
|
|
while remain > 0:
|
|
while remain > 0:
|
|
|
step = min(remain, int(h * 0.5))
|
|
step = min(remain, int(h * 0.5))
|
|
|
- _adb_swipe_up(ex, step)
|
|
|
|
|
|
|
+ _swipe_next_batch(ex, step)
|
|
|
remain -= step
|
|
remain -= step
|
|
|
human_sleep(2)
|
|
human_sleep(2)
|
|
|
unknown_skip_streak = 0
|
|
unknown_skip_streak = 0
|
|
@@ -2890,7 +2966,7 @@ def step3_swipe_and_enter(ex: SafeExecutor, keyword: str, brand: str = "", task:
|
|
|
remain = total_scroll_px
|
|
remain = total_scroll_px
|
|
|
while remain > 0:
|
|
while remain > 0:
|
|
|
step = min(remain, int(h * 0.5))
|
|
step = min(remain, int(h * 0.5))
|
|
|
- _adb_swipe_up(ex, step)
|
|
|
|
|
|
|
+ _swipe_next_batch(ex, step)
|
|
|
remain -= step
|
|
remain -= step
|
|
|
human_sleep(2)
|
|
human_sleep(2)
|
|
|
continue
|
|
continue
|
|
@@ -2905,7 +2981,7 @@ def step3_swipe_and_enter(ex: SafeExecutor, keyword: str, brand: str = "", task:
|
|
|
swipe_dist = max(target_y - int(h * 0.15), int(h * 0.15))
|
|
swipe_dist = max(target_y - int(h * 0.15), int(h * 0.15))
|
|
|
else:
|
|
else:
|
|
|
swipe_dist = int(h * 0.3)
|
|
swipe_dist = int(h * 0.3)
|
|
|
- _adb_swipe_up(ex, swipe_dist)
|
|
|
|
|
|
|
+ _swipe_next_batch(ex, swipe_dist)
|
|
|
total_scroll_px += swipe_dist
|
|
total_scroll_px += swipe_dist
|
|
|
human_sleep(2)
|
|
human_sleep(2)
|
|
|
batch_no += 1
|
|
batch_no += 1
|