# -*- coding:utf-8 -*- import requests, re, json, base64 import io, os, random import time, cv2, json from PIL import Image from functools import partial from io import BytesIO from urllib3.util import proxy from detect.module.use_ua import randomUA from detect.module.gap import quekou import subprocess subprocess.Popen = partial(subprocess.Popen, encoding='utf-8') import execjs class slide(): def __init__(self): self.headers = randomUA() self.t = round(time.time() * 1000) def __ease_out_expo(self, sep): if sep == 1: return 1 else: return 1 - pow(2, -10 * sep) def get_slide_track(self, vdict): distance = self.huak(vdict) slide_track = [ [random.randint(-50, -10), random.randint(-50, -10), 0], [0, 0, 0], ] count = 30 + int(distance / 2) t = random.randint(50, 100) _x = 0 _y = 0 for i in range(count): x = round(self.__ease_out_expo(i / count) * distance) t += random.randint(10, 20) if x == _x: continue slide_track.append([x, _y, t]) _x = x slide_track.append(slide_track[-1]) return slide_track def tp_huanyuan(self, content): _img = Image.open(BytesIO(content)) _Ge = [{"x": -157, "y": -58}, {"x": -145, "y": -58}, {"x": -265, "y": -58}, {"x": -277, "y": -58}, {"x": -181, "y": -58}, {"x": -169, "y": -58}, {"x": -241, "y": -58}, {"x": -253, "y": -58}, {"x": -109, "y": -58}, {"x": -97, "y": -58}, {"x": -289, "y": -58}, {"x": -301, "y": -58}, {"x": -85, "y": -58}, {"x": -73, "y": -58}, {"x": -25, "y": -58}, {"x": -37, "y": -58}, {"x": -13, "y": -58}, {"x": -1, "y": -58}, {"x": -121, "y": -58}, {"x": -133, "y": -58}, {"x": -61, "y": -58}, {"x": -49, "y": -58}, {"x": -217, "y": -58}, {"x": -229, "y": -58}, {"x": -205, "y": -58}, {"x": -193, "y": -58}, {"x": -145, "y": 0}, {"x": -157, "y": 0}, {"x": -277, "y": 0}, {"x": -265, "y": 0}, {"x": -169, "y": 0}, {"x": -181, "y": 0}, {"x": -253, "y": 0}, {"x": -241, "y": 0}, {"x": -97, "y": 0}, {"x": -109, "y": 0}, {"x": -301, "y": 0}, {"x": -289, "y": 0}, {"x": -73, "y": 0}, {"x": -85, "y": 0}, {"x": -37, "y": 0}, {"x": -25, "y": 0}, {"x": -1, "y": 0}, {"x": -13, "y": 0}, {"x": -133, "y": 0}, {"x": -121, "y": 0}, {"x": -49, "y": 0}, {"x": -61, "y": 0}, {"x": -229, "y": 0}, {"x": -217, "y": 0}, {"x": -193, "y": 0}, {"x": -205, "y": 0}] w_sep, h_sep = 10, 58 new_img = Image.new('RGB', (260, 116)) for idx in range(len(_Ge)): x = abs(_Ge[idx]['x']) y = 58 if _Ge[idx]['y'] == -58 else 0 img_cut = _img.crop((x, y, x + w_sep, y + h_sep)) new_x = idx % 26 * 10 new_y = 0 if idx < 26 else 58 new_img.paste(img_cut, (new_x, new_y)) img_byte = BytesIO() new_img.save(img_byte, 'png') return img_byte.getvalue() def huak(self, vdict): count = 1 bgbase64 = "" tpbase64 = "" for idv, p_url in vdict.items(): p_url = 'http://static.geetest.com/' + p_url # print(p_url) vcode = requests.get(p_url, headers=self.headers) text = vcode.content if idv == 'bg': text = self.tp_huanyuan(text) bgbase64 = base64.encodebytes(text).decode() else: tpbase64 = base64.encodebytes(text).decode() count += 1 if bgbase64 and tpbase64: dis = quekou().get_distance(bgbase64, tpbase64) else: dis = 0 return dis class Geetest2(): def __init__(self): self.header = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36", } # 获取当前文件的目录 current_dir = os.path.dirname(__file__) with open(os.path.join(current_dir, 'module', 'crack_geetest2x.js'), "r", encoding="gb2312", errors='ignore') as f: js_encrypt = f.read() self.js = execjs.compile(js_encrypt) self.t = round(time.time() * 1000) self.gct_vdi = {} self.gct_volue = ['', ''] # 初始值 self.token_vdi = {} self.timeout = (7, 9.05) self.geetest_type = 'slide' self.geetest_path = "/static/js/geetest.6.0.9.js" def new_requests(self): self.session = requests.session() self.session.headers = self.header def get_vsion(self, http, gt, proxies, pparmas): url = "https://api.geetest.com/gettype.php" params = { "gt": gt, "callback": f"geetest_{self.t}" } try: respe = http.get(url=url, params=params, proxies=proxies).text except Exception as e: if proxy: if pparmas: vdict = {'result': '错误', 'message': f'代理IP超时!,请重新更换代理IP,{e}', 'proxy': proxies, 'pparmas': pparmas} else: vdict = {'result': '错误', 'message': f'代理IP超时!,请重新更换代理IP,{e}', 'proxy': proxies} else: vdict = {'result': '错误', 'message': f'请求错误,{e}'} return vdict try: data = json.loads(respe[22:-1])["data"] except: vdict = {'result': '错误', 'type': 'auto', 'message': respe} return vdict self.geetest_type = data["type"] self.geetest_path = data['path'] self.token_vdi[gt] = 1 def get_tp(self, gt, challenge, type_, proxies=None, pparmas=None): self.new_requests() self.t = round(time.time() * 1000) if pparmas: h_list = re.findall('([\w-]+):(.+)', pparmas) for idx in h_list: print('新增协议头' + str(idx)) self.session.headers[idx[0]] = idx[1].replace('\r', '').replace('\n', '').replace('\r\n', '') print(self.session.headers) if not self.token_vdi.get('gt', ''): self.get_vsion(self.session, gt, proxies, pparmas) url = f"https://api.geetest.com/get.php" params = { "gt": gt, "challenge": challenge, "product": "popup", "offline": "false", "protocol": "https://", "type": self.geetest_type, "path": self.geetest_path, "callback": f"geetest_{self.t}" } response = self.session.get(url, params=params, timeout=self.timeout).text geetest_type = self.geetest_type if geetest_type == 'slide': data = json.loads(response[22:-1]) else: try: data = json.loads(response[22:-1])["data"] except: vdict = {'result': '错误', 'type': type_, 'message': response} return vdict ##print(data) nc, ns = data['c'], data['s'] if geetest_type == 'slide': data = json.loads(response[22:-1]) else: try: data = json.loads(response[22:-1])["data"] except: vdict = {'result': '错误', 'type': type_, 'message': json.loads(response)} return vdict ##print(data) nc, ns = data['c'], data['s'] gct_url = 'http://static.geetest.com' + data['gct_path'] ##print('gct地址:', gct_url) if geetest_type == 'click': return {'result': '请求类型不是滑块', 'type': type_, 'gt': gt, 'challenge': challenge, '当前类型': '点选'} if geetest_type == 'slide': # slide challenge = data['challenge'] # 这里challenge改变了 bg = data['bg'] # 背景图片 slice = data['slice'] # 缺口图片 vdict = { "bg": bg, "slice": slice, } slide_track = slide().get_slide_track(vdict) imgload = 37 w = self.js.call('get_slide_w', nc, ns, gt, challenge, slide_track, imgload, self.gct_volue) params = ( ('gt', gt), ('challenge', challenge), ('w', w), ('callback', f"geetest_{self.t}"), ) response = self.session.get('https://api.geetest.com/ajax.php', params=params, proxies=proxies, timeout=self.timeout).text data = json.loads(response[22:-1]) validate = data.get('validate') vdict = {'result': data.get('message'), 'type': geetest_type, 'gt': gt, 'challenge': challenge, 'validate': validate} return vdict if __name__ == '__main__': a = Geetest2() headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36", } url = "https://seo.juziseo.com/class/gtcode/msg/StartMsgCaptchaServlet.php" url = "https://gsxt.hlj.gov.cn/registerValidate.jspx" for i in range(1): index = requests.get(url, headers=headers) # print(index.text) html = index.json() challenge = html["challenge"] gt = html["gt"] print('gt', gt, 'challenge', challenge) r = a.get_tp(gt, challenge, 'auto', '') print(r)