增强虎牙滑块验证重试
This commit is contained in:
@@ -86,6 +86,7 @@ class HuyaVerificationSolver:
|
|||||||
self.url_param_map: dict[str, str] = {}
|
self.url_param_map: dict[str, str] = {}
|
||||||
self.strategy_url = ""
|
self.strategy_url = ""
|
||||||
self.js_ctx = None
|
self.js_ctx = None
|
||||||
|
self.behavior_events: list[dict] = []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _auth_page_url() -> str:
|
def _auth_page_url() -> str:
|
||||||
@@ -186,12 +187,16 @@ class HuyaVerificationSolver:
|
|||||||
"urlParamMap": self.url_param_map,
|
"urlParamMap": self.url_param_map,
|
||||||
"wupData": "",
|
"wupData": "",
|
||||||
"page": self._auth_page_url(),
|
"page": self._auth_page_url(),
|
||||||
"behavior": "%5B%5D",
|
"behavior": self._encode_behavior(),
|
||||||
"info": self.sdid,
|
"info": self.sdid,
|
||||||
}
|
}
|
||||||
payload.update(extra)
|
payload.update(extra)
|
||||||
return {"appId": "5002", "data": payload}
|
return {"appId": "5002", "data": payload}
|
||||||
|
|
||||||
|
def _encode_behavior(self) -> str:
|
||||||
|
"""编码浏览器行为,失败重试时会携带前一次点击记录。"""
|
||||||
|
return quote(json.dumps(self.behavior_events, separators=(",", ":")), safe="~()*!.'")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _extract_strategy_url(challenge_payload: dict | str) -> str:
|
def _extract_strategy_url(challenge_payload: dict | str) -> str:
|
||||||
"""兼容完整响应、data 子对象、data URL 字符串三种输入。"""
|
"""兼容完整响应、data 子对象、data URL 字符串三种输入。"""
|
||||||
@@ -228,6 +233,7 @@ class HuyaVerificationSolver:
|
|||||||
self.url_param_map.get("mobile", ""),
|
self.url_param_map.get("mobile", ""),
|
||||||
len(self.url_param_map.get("param", "")),
|
len(self.url_param_map.get("param", "")),
|
||||||
)
|
)
|
||||||
|
self.behavior_events = []
|
||||||
|
|
||||||
def _restore_slider_background(self, bg_bytes: bytes, segment: str, huyapk: str) -> bytes:
|
def _restore_slider_background(self, bg_bytes: bytes, segment: str, huyapk: str) -> bytes:
|
||||||
recover_list = self.js_ctx.call("get_regoin_arr", segment, huyapk)
|
recover_list = self.js_ctx.call("get_regoin_arr", segment, huyapk)
|
||||||
@@ -283,22 +289,19 @@ class HuyaVerificationSolver:
|
|||||||
"endTime": int(track_points[-1][-1]) - int(track_points[0][-1]),
|
"endTime": int(track_points[-1][-1]) - int(track_points[0][-1]),
|
||||||
}
|
}
|
||||||
act = self.js_ctx.call("get_act", act_data, self.huyapk)
|
act = self.js_ctx.call("get_act", act_data, self.huyapk)
|
||||||
behavior = quote(
|
self.behavior_events.append({
|
||||||
json.dumps([{
|
"action": "mousedown",
|
||||||
"action": "mousedown",
|
"id": "",
|
||||||
"id": "",
|
"txt": "",
|
||||||
"txt": "",
|
"clientX": track_points[0][0],
|
||||||
"clientX": track_points[0][0],
|
"clientY": track_points[0][1],
|
||||||
"clientY": track_points[0][1],
|
"clientWidth": 350,
|
||||||
"clientWidth": 350,
|
"clientHeight": 268,
|
||||||
"clientHeight": 268,
|
"isTrusted": True,
|
||||||
"isTrusted": True,
|
"timeStamp": random.randint(1800, 5500),
|
||||||
"timeStamp": 1829,
|
"nowTime": int(time.time() * 1000),
|
||||||
"nowTime": int(time.time() * 1000),
|
})
|
||||||
}], separators=(",", ":")),
|
payload = self._build_common_payload({"act": act, "ver": 5})
|
||||||
safe="~()*!.'",
|
|
||||||
)
|
|
||||||
payload = self._build_common_payload({"behavior": behavior, "act": act, "ver": 5})
|
|
||||||
return self._submit_verify(url, payload)
|
return self._submit_verify(url, payload)
|
||||||
|
|
||||||
def _send_click_verify(self, url: str, points: list[list[int]]) -> dict:
|
def _send_click_verify(self, url: str, points: list[list[int]]) -> dict:
|
||||||
@@ -338,8 +341,8 @@ class HuyaVerificationSolver:
|
|||||||
"nowTime": item[2],
|
"nowTime": item[2],
|
||||||
})
|
})
|
||||||
|
|
||||||
behavior = quote(json.dumps(behavior_list, separators=(",", ":")), safe="~()*!.'")
|
self.behavior_events.extend(behavior_list)
|
||||||
payload = self._build_common_payload({"behavior": behavior, "act": act, "ver": 5})
|
payload = self._build_common_payload({"act": act, "ver": 5})
|
||||||
return self._submit_verify(url, payload)
|
return self._submit_verify(url, payload)
|
||||||
|
|
||||||
def _submit_verify(self, url: str, payload: dict) -> dict:
|
def _submit_verify(self, url: str, payload: dict) -> dict:
|
||||||
@@ -396,11 +399,31 @@ class HuyaVerificationSolver:
|
|||||||
|
|
||||||
self._compile_js(dx_js)
|
self._compile_js(dx_js)
|
||||||
point_payload = self._build_common_payload({"ver": 5})
|
point_payload = self._build_common_payload({"ver": 5})
|
||||||
point = self._get_track_point(gurl, point_payload)
|
last_result: dict = {}
|
||||||
logger.debug(f"虎牙验证识别结果: {point}")
|
for index in range(3):
|
||||||
if isinstance(point, list):
|
if index:
|
||||||
return self._send_click_verify(vurl, point)
|
time.sleep(0.4)
|
||||||
return self._send_slider_verify(vurl, int(point))
|
point_payload = self._build_common_payload({"ver": 5})
|
||||||
|
logger.info("虎牙验证失败后重试: {}/3", index + 1)
|
||||||
|
|
||||||
|
point = self._get_track_point(gurl, point_payload)
|
||||||
|
logger.debug(f"虎牙验证识别结果: {point}")
|
||||||
|
if isinstance(point, list):
|
||||||
|
last_result = self._send_click_verify(vurl, point)
|
||||||
|
else:
|
||||||
|
last_result = self._send_slider_verify(vurl, int(point))
|
||||||
|
|
||||||
|
if isinstance(last_result, dict) and (last_result.get("authId") or last_result.get("nextAuthUrl")):
|
||||||
|
return last_result
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"虎牙验证提交未通过: returnCode={}, message={} ({}/3)",
|
||||||
|
last_result.get("returnCode") if isinstance(last_result, dict) else "",
|
||||||
|
last_result.get("message") if isinstance(last_result, dict) else "",
|
||||||
|
index + 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
return last_result
|
||||||
|
|
||||||
def solve(self, challenge_payload: dict | str) -> dict:
|
def solve(self, challenge_payload: dict | str) -> dict:
|
||||||
"""提交虎牙风控验证,返回 vurl 响应中的 data。"""
|
"""提交虎牙风控验证,返回 vurl 响应中的 data。"""
|
||||||
|
|||||||
Reference in New Issue
Block a user