(
self,
session: AccountSessionState,
request: CaptchaVerifyPayloadRequest,
)
| 108 | return [CaptchaPoint.model_validate(item) for item in raw_points] |
| 109 | |
| 110 | def build_verify_payload( |
| 111 | self, |
| 112 | session: AccountSessionState, |
| 113 | request: CaptchaVerifyPayloadRequest, |
| 114 | ) -> dict[str, Any]: |
| 115 | sess = (request.sess or "").strip() or session.captcha_challenge_sess |
| 116 | if not sess: |
| 117 | raise BadRequestError("缺少 challenge sess,请先拉一次验证码 challenge 或手动传 sess") |
| 118 | |
| 119 | points = request.points |
| 120 | if not points: |
| 121 | points = self.extract_points_from_ocr(session.captcha_challenge_ocr) |
| 122 | |
| 123 | answer = self.build_click_answer(points) |
| 124 | collect = self._normalize_collect(request.collect) |
| 125 | settings = get_settings() |
| 126 | payload: dict[str, Any] = { |
| 127 | "aid": settings.tencent_captcha_aid, |
| 128 | "protocol": "https", |
| 129 | "sess": sess, |
| 130 | "ans": json.dumps(answer, ensure_ascii=False, separators=(",", ":")), |
| 131 | "collect": collect, |
| 132 | "tlg": str(len(collect)), |
| 133 | "eks": (request.eks or "").strip(), |
| 134 | } |
| 135 | pow_answer = (request.pow_answer or "").strip() |
| 136 | if pow_answer: |
| 137 | payload["pow_answer"] = pow_answer |
| 138 | if request.pow_calc_time is not None: |
| 139 | payload["pow_calc_time"] = str(int(request.pow_calc_time)) |
| 140 | if request.vdata: |
| 141 | payload["vData"] = request.vdata |
| 142 | |
| 143 | return { |
| 144 | "endpoint": "/cap_union_new_verify", |
| 145 | "method": "POST", |
| 146 | "content_type": "application/x-www-form-urlencoded; charset=UTF-8", |
| 147 | "answer": answer, |
| 148 | "payload": payload, |
| 149 | "notes": [ |
| 150 | "collect 来自 TDC.getData(true) 后再 decodeURIComponent。", |
| 151 | "eks 来自 TDC.getInfo().info。", |
| 152 | "tlg 等于 collect 解码后的字符串长度。", |
| 153 | "pow_answer 是 prefix + suffix,不是单独的整数 suffix。", |
| 154 | "vData 只有 window.getVData 存在时才会附加,当前源码里它是可选字段。", |
| 155 | ], |
| 156 | } |
| 157 | |
| 158 | def solve_pow(self, prefix: str, target_md5: str, *, timeout_ms: int = 30000) -> dict[str, str]: |
| 159 | normalized_prefix = prefix.strip() |
no test coverage detected