def do_click_verify(self): start_time = get_timestamp() img_url = self.urls["resources_host"] + self._geetest_params["pic"] self.logger.info("challenge: {0}, image url:{1}".format( self.challenge, img_url)) click_img = self.fetch(url=img_url, get_json=False, get_bytes=True) point_list = self._get_coordinate(vtype="click", image=click_img) a = self.__get_a_param(point_list=point_list) trace_list = self._generate_trace(vtype="click") P0o = hb_click_trace_encrypt(ctx=self.__click_ctx, trace_list=trace_list) info = { "lang": "zh-cn", "tt": m5_encrypt(ctx=self.__fullpage_ctx, message=P0o, arr=self._geetest_params.get("c"), mstr=self._geetest_params.get("s")), "pic": self._geetest_params.get("pic"), "a": a, "ep": self.get_ep_param(vtype="click", start_time=start_time), } passtime = get_timestamp() - start_time info.update({ "passtime": passtime, "rp": get_md5("".join([self.gt, self.challenge[:32], str(passtime)])) }) aes_key = generate_aes_key() encrypt_key_msg = rsa_encrypt(ctx=self.__fullpage_ctx, message=aes_key) encrypt_msg = final_encrypt(ctx=self.__fullpage_ctx, message=info, aes_key=aes_key) ret_info = self.fetch( self.urls["verify"], extra_params={"w": encrypt_msg + encrypt_key_msg}) if not self.debug: trace_info = { "fid": self.challenge, "trace_type": "click", "image": base64_encode(click_img), "point_list": point_list, "params": self._generate_trace_params.get("click", {}), "trace_list": trace_list, "result": ret_info.get("result") } TraceInfo(**trace_info).save() return ret_info
def do_first_verify(self): start_time = get_timestamp() # trace_list = self._generate_trace(vtype="first") # trace_list_info, _ = self._add_click_point(trace_list=trace_list, last_point=trace_list[-1]) trace_list_info = [] P0o = hb_trace_encrypt(ctx=self.__fullpage_ctx, trace_list=trace_list_info) S0o = hb_trace_encrypt(ctx=self.__fullpage_ctx, trace_list=[]) magic_msg = self._get_i_param(sep="magic data") info = { "lang": "zh-cn", "type": "fullpage", "tt": m5_encrypt(ctx=self.__fullpage_ctx, message=P0o, arr=self._geetest_params.get("c"), mstr=self._geetest_params.get("s")), "light": "INPUT_0", "s": get_md5(text=hb_encrypt(ctx=self.__fullpage_ctx, message=S0o) ), # md5(D8[B5Y.c78(1283)](S0o)) "h": get_md5( text=hb_encrypt(ctx=self.__fullpage_ctx, message=magic_msg)), "hh": get_md5(text=magic_msg), # md5(i) "hi": get_md5(text=self._get_i_param(sep="!!")), # md5(i) "ep": self.get_ep_param(), } end_time = get_timestamp() passtime = end_time - start_time info.update({ "passtime": passtime, "rp": get_md5("".join([self.gt, self.challenge, str(passtime)])) }) encrypt_msg = final_encrypt(ctx=self.__fullpage_ctx, message=info, aes_key=self.__aes_key) ret_info = self.fetch(self.urls["verify"], extra_params={"w": encrypt_msg}) self.logger.debug("First verify result:{0}, challenge:{1}".format( ret_info, self.challenge)) return ret_info
def _generate_tm(): current_ts = get_timestamp() return { "a": current_ts, "b": current_ts + random.randint(90, 100), "c": current_ts + random.randint(90, 100), "d": 0, "e": 0, "f": current_ts + random.randint(1, 5), "g": current_ts + random.randint(1, 5), "h": current_ts + random.randint(1, 5), "i": current_ts + random.randint(1, 5), "j": current_ts + random.randint(1, 5), "k": 0, "l": current_ts + random.randint(1, 5), "m": current_ts + random.randint(90, 100), "n": current_ts + random.randint(95, 105), "o": current_ts + random.randint(95, 105), "p": current_ts + random.randint(420, 430), "q": current_ts + random.randint(420, 430), "r": current_ts + random.randint(455, 460), "s": current_ts + random.randint(535, 545), "t": current_ts + random.randint(535, 545), "u": current_ts + random.randint(535, 545) }
def start(self): source = self.fetch(self.urls["index"], get_json=False) cookies = self.get_cookies(js_code=source) captcha_url = self.urls["captcha"].format(get_timestamp()) challenge_info = self.fetch(captcha_url, cookies=cookies) self.gt = challenge_info.get("gt") self.challenge = challenge_info.get("challenge") self.offline = not bool(challenge_info.get("success")) if self.offline: return get_md5(text=self.challenge) self.new_captcha = challenge_info.get("new_captcha", False) # self.token = self.get_token() self._type_info = self.get_type_info() self._geetest_params = self.get_geetest_params() verify_ret = self.do_first_verify() if "validate" in verify_ret.keys(): return verify_ret.get("validate", "").split("|")[0] else: verify_type = verify_ret.get("result") self._geetest_params = self.get_next_params( verify_type=verify_type) verify_func = self.verify_type[verify_type]["func"] vret = verify_func() if vret.get("status") == "error": pass else: return vret.get("data", {}).get("validate", "").split("|")[0]
def _generate_trace_between_two_point(self, point_a, point_b, radio=10): x1, y1 = point_a x2, y2 = point_b dx, dy = x2 - x1, y2 - y1 abs_x, abs_y = operator.abs(dx), operator.abs(dy) slope = dy / dx get_ty = lambda tx: (tx - x1) * slope + y1 ox, oy = tuple( map(lambda t: operator.add if t > 0 else operator.sub, (dx, dy))) base_step_x = abs_x // radio step_x_rng = base_step_x // 2 get_val = lambda x, y: random.randint(int(x) - y, int(x) + y) sx = 0 lx = x1 trace_list = [] while True: step_x = get_val(base_step_x, step_x_rng) tx = ox(lx, step_x) ty = get_ty(tx) ts = int(get_timestamp()) x = get_val(tx, 5) y = get_val(ty, 5) trace_list.append([x, y, ts]) sx += step_x lx = x if abs_x - sx <= base_step_x: break return trace_list
def do_first_verify(self): start_time = get_timestamp() trace_list = self._generate_trace(vtype="first") P0o = hb_trace_encrypt(ctx=self.__ctx, trace_list=trace_list) S0o = hb_trace_encrypt(ctx=self.__ctx, trace_list=[]) magic_msg = self._get_i_param(sep="magic data") info = { "lang": "zh-cn", "type": "fullpage", "tt": m5_encrypt(ctx=self.__ctx, message=P0o, arr=self._geetest_params.get("c"), mstr=self._geetest_params.get("s")), "light": "INPUT_0", "s": get_md5(text=hb_encrypt( ctx=self.__ctx, message=S0o)), # md5(D8[B5Y.c78(1283)](S0o)) "h": get_md5(text=hb_encrypt(ctx=self.__ctx, message=magic_msg)), "hh": get_md5(text=magic_msg), # md5(i) "hi": get_md5(text=self._get_i_param(sep="!!")), # md5(i) "ep": self.get_ep_param(), } end_time = get_timestamp() passtime = end_time - start_time info.update({ "passtime": passtime, "rp": get_md5("".join([self.gt, self.challenge, str(passtime)])) }) encrypt_msg = get_Q0o(ctx=self.__ctx, message=info, aes_key=self.__aes_key) ret_info = self.fetch(self.urls["verify"], extra_params={"w": encrypt_msg}) print(ret_info) return ret_info.get("data", {})
def do_click_verify(self): start_time = get_timestamp() img_url = self.urls["resources_host"] + self._geetest_params["pic"] print(img_url) click_img = self.fetch(url=img_url, get_json=False, get_bytes=True) point_list = self._get_coordinate(vtype="click", image_info={ "type": "click", "image": click_img }) a = self.__get_a_param(point_list=point_list) trace_list = self._generate_trace(vtype="click") P0o = hb_click_trace_encrypt(ctx=self.__click_ctx, trace_list=trace_list) info = { "lang": "zh-cn", "tt": m5_encrypt(ctx=self.__ctx, message=P0o, arr=self._geetest_params.get("c"), mstr=self._geetest_params.get("s")), "pic": self._geetest_params.get("pic"), "a": a, "ep": self.get_ep_param(vtype="click"), } end_time = get_timestamp() passtime = end_time - start_time info.update({ "passtime": passtime, "rp": get_md5("".join([self.gt, self.challenge[:32], str(passtime)])) }) aes_key = generate_aes_key() encrypt_key_msg = rsa_encrypt(ctx=self.__ctx, message=aes_key) encrypt_msg = get_Q0o(ctx=self.__ctx, message=info, aes_key=aes_key) ret_info = self.fetch( self.urls["verify"], extra_params={"w": encrypt_msg + encrypt_key_msg}) return ret_info
def get_request_params_info(self, extra_info): info = { "gt": self.gt, "challenge": self.challenge, "lang": "zh-cn", "pt": "0", "callback": "geetest_{0}".format(get_timestamp()) } info.update(extra_info or {}) return info
def do_slide_verify(self): start_time = get_timestamp() trace_list = self._generate_trace(vtype="slide") P0o = hb_slide_trace_encrypt(ctx=self.__slide_ctx, trace_list=trace_list) J72 = "64" # last point x info = { "lang": "zh-cn", "aa": m5_encrypt(ctx=self.__fullpage_ctx, message=P0o, arr=self._geetest_params.get("c"), mstr=self._geetest_params.get("s")), "imgload": random.randint(90, 150), "userresponse": j5_encrypt(ctx=self.__slide_ctx, vint=int(J72), vstr=self.challenge), "ep": self.get_ep_param(vtype="slide"), } end_time = get_timestamp() passtime = end_time - start_time info.update({ "passtime": passtime, "rp": get_md5("".join([self.gt, self.challenge[:32], str(passtime)])) }) aes_key = generate_aes_key() encrypt_key_msg = rsa_encrypt(ctx=self.__fullpage_ctx, message=aes_key) encrypt_msg = final_encrypt(ctx=self.__fullpage_ctx, message=info, aes_key=aes_key) ret_info = self.fetch( self.urls["verify"], extra_params={"w": encrypt_msg + encrypt_key_msg}) return ret_info
def generate_beenline_trace_between_two_point(point_a, point_b, radio=0.1): x1, y1 = point_a x2, y2 = point_b dx, dy = x2 - x1, y2 - y1 abs_x, abs_y = operator.abs(dx), operator.abs(dy) slope = dy / dx get_ty = lambda tx: (tx - x1) * slope + y1 ox, oy = tuple( map(lambda t: operator.add if t > 0 else operator.sub, (dx, dy))) base_step_x = abs_x // radio or 5 step_x_rng = base_step_x // 2 or 2 get_val = lambda x, y: random.randint(int(x) - y, int(x) + y) sx = 0 lx = x1 trace_list = list() # first point trace_list.append([x1, y1, int(get_timestamp())]) while True: time.sleep(random.randint(15, 40) / 1000) step_x = get_val(base_step_x, step_x_rng) tx = ox(lx, step_x) ty = get_ty(tx) ts = int(get_timestamp()) x = get_val(tx, 5) y = get_val(ty, 5) trace_list.append([x, y, ts]) sx += step_x lx = x if abs_x - sx <= base_step_x: break # last point trace_list.append([x2, y2, int(get_timestamp())]) return trace_list
def get_challenge(self): source = self.fetch(self.urls["index"], get_json=False) cookies = self.get_cookies(js_code=source) captcha_url = self.urls["captcha"].format(get_timestamp()) challenge_info = self.fetch(captcha_url, cookies=cookies) gt = challenge_info.get("gt") challenge = challenge_info.get("challenge") offline = not bool(challenge_info.get("success")) validate = "" if offline: if challenge: validate = get_md5(text=challenge) else: raise GetParamsError(extra_msg="challenge_info") return gt, challenge, validate
def _generate_trace(self, vtype="first"): start_time = get_timestamp() if vtype == "first": search_button_pos = tuple( map(lambda t: random.randint(t - 2, t + 2), self._search_button_pos)) random_pos = (random.randint(100, 800), random.randint(100, 400)) trace_list = self._generate_trace_between_two_point( random_pos, search_button_pos, start_time=start_time) elif vtype == "slide": trace_list = [] elif vtype == "click": trace_list = [] ca_list = [] # generate random start point start_point = (random.randint(800, 1200), random.randint(300, 600)) self._click_points.insert(0, start_point) for i in range(len(self._click_points) - 1): pa = self._click_points[i] pb = self._click_points[i + 1] tr_lst = self._generate_trace_between_two_point( point_a=pa, point_b=pb, vtype="click", start_time=start_time) last_point = tr_lst[-1] ca_list.append(last_point) points_info, last_ts = self._add_click_point( trace_list=tr_lst, last_point=last_point) trace_list.extend(points_info) start_time = last_ts self._click_points = ca_list if self.debug: draw_trace(trace_list) else: trace_list = [] self.logger.debug("challenge:{0}, type:{1}, trace_list:{2}".format( self.challenge, vtype, trace_list)) return trace_list
def generate_mouse_trace_between_two_point(point_a, point_b, rp=(), dense_radio=None, time_rng=None, start_time=None, show=False): """ 生成两点之间的鼠标移动轨迹 :param point_a: (x1, y1) 起始点 :param point_b: (x2, y2) 结束点 :param rp: ((rp_x, rp_y)...) 调节参数集 :param dense_radio: 点密集程度 :param time_rng: 每个点耗时范围 :param start_time: 开始时间 :param show: 是否画出s/t, y/x 之间的关系图 :return: [(x, y, ts)...] """ dense_radio = dense_radio or 0.15 time_rng = time_rng or (12, 28) if len(rp) == 0: rp_x_y_relate = (0.2, 0.4) rp_s_t_relate = [] else: rp_x_y_relate, *rp_s_t_relate = rp rp_x, rp_y = rp_x_y_relate if operator.abs(point_a[0] - point_b[0]) <= 2 or operator.abs(point_a[1] - point_b[1]) <= 2: get_y = get_x_y_line_relate(point_a, point_b) else: get_y = get_x_y_relate(point_a, point_b, rp_x=rp_x, rp_y=rp_y) distance = calc_distance(point_a, point_b) point_num = get_range(round(distance * dense_radio), rng=2) ts = [random.randint(time_rng[0], time_rng[1]) for _ in range(point_num)] get_s = get_distance_time_relate(point_a, point_b, ts=ts, rp=rp_s_t_relate) if show: ii = 0 for i in ts: ii += i plt.scatter(ii, get_s(ii), color="y") plt.show() xs = [] ys = [] rts = [] start_time = start_time or int(get_timestamp()) ax = plt.gca() ax.invert_yaxis() ax.xaxis.set_ticks_position('top') x0, y0 = point_a lt = 0 ls = 0 opt = operator.add if point_b[0] - point_a[0] >= 0 else operator.sub for t in ts: lt += t s = get_s(lt) - ls x_y = lambda x, y: (x - x0)**2 + (y - y0)**2 tv = s**2 dx = point_b[0] - x0 mx = min(operator.abs(dx), s) rng_x = (x0, opt(x0, mx)) if opt == operator.add else (opt(x0, mx), x0) nx, ny = calc_x_y(get_y=get_y, x_y=x_y, tv=tv, rng_x=rng_x, opt=opt) xs.append(round(nx)) ys.append(round(ny)) x0, y0 = (nx, ny) ls += s current_time = start_time + t rts.append(current_time) plt.scatter(nx, ny, color="b") start_time = current_time if show: plt.show() trace_list = list(zip(xs, ys, rts)) return trace_list
def _get_i_param(self, sep="!!"): i_str = "3668!!17548!!CSS1Compat!!50!!-1!!-1!!-1!!-1!!3!!-1!!-1!!-1!!9!!9!!-1!!9!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!9!!-1!!4!!-1!!-1!!1600!!0!!1600!!0!!1920!!353!!1920!!1080!!zh-CN!!zh-CN,zh!!-1!!1!!24!!Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36!!1!!1!!1920!!1080!!1920!!1080!!1!!1!!1!!-1!!Linux x86_64!!0!!-8!!04f7eb201d3cc0991ab472b909027874!!2e2d74424f3cc8b7d88f16655f148d75!!internal-pdf-viewer,mhjfbmdgcfjbbpaeojofohoefgiehjai,internal-nacl-plugin!!0!!-1!!0!!8!!Arial,Courier,CourierNew,Helvetica,Times,TimesNewRoman!!1542365354985!!3,177,0,0,0,0,0,2,10715,6,3,3,8,307,307,438,613,613,613,-1!!-1!!-1!!61!!6!!-1!!-1!!14!!false!!false" i_list = i_str.split("!!") i_list[64] = str(get_timestamp()) return sep.join(i_list)
def get_ep_param(self, vtype="first", **kwargs): base_info = { "f": get_md5("".join([self.gt, self.challenge])), "te": False, # touchEvent "me": True, # mouseEvent "tm": self._generate_tm() } if vtype == "first": # tm < fp < lp < ts ep_info = { "v": "8.6.1", "ip": "10.8.10.128", "de": False, # deviceorientation "ven": "Intel Open Source Technology Center", "ren": "Mesa DRI Intel(R) Sandybridge Mobile ", "ac": "f930496cb2084fa8e08a507beb9e3871", # md5(window.AudioContext) "pu": False, # puppet "ph": False, # phantom "ni": False, # nightmare "se": False, # selenium "fp": [ "move", random.randint(750, 850), random.randint(300, 400), get_timestamp(), "pointermove" ], "lp": [ "up", random.randint(800, 1200), random.randint(250, 450), get_timestamp() + random.randint(500, 1500), "pointerup" ], "em": { "ph": 0, "cp": 0, "ek": "11", "wd": 0, "nt": 0, "si": 0, "sc": 0 }, "by": -1, "ts": get_timestamp(), } elif vtype == "slide": ep_info = {"v": "7.4.3"} elif vtype == "click": ca = [] lts = kwargs.get("start_time") for index, p in enumerate(self._click_points): x, y, ts = p dt = ts - lts if index == len(self._click_points) - 1: tp = 3 else: tp = 1 ca.append({"x": x, "y": y, "t": tp, "dt": dt}) lts = ts ep_info = {"v": "2.6.4", "ca": ca} else: ep_info = {} ep_info.update(base_info) return ep_info