2025年4月9日 星期三 乙巳(蛇)年 正月初十 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

极验二代滑块验证码

时间:06-25来源:作者:点击数:50

极验二代滑块验证码

  • # -*- coding:utf-8 -*-
  • import os
  • import random
  • import re
  • import ssl
  • import time
  • from urllib.request import urlretrieve
  • import undetected_chromedriver as uc
  • from PIL import Image
  • from lxml import etree
  • from selenium import webdriver
  • from selenium.webdriver import ActionChains
  • from selenium.webdriver.common.by import By
  • from selenium.webdriver.support import expected_conditions as EC
  • from selenium.webdriver.support.wait import WebDriverWait
  • class CrackGeetest():
  • def __init__(self):
  • self.url = 'https://gsxt.amr.jiangxi.gov.cn/indexmain.jsp?'
  • self.company_name = "南昌银行"
  • def chrome_operate(self):
  • chrome_options = webdriver.ChromeOptions()
  • # chrome_options.add_argument('--headless')
  • chrome_options.add_argument('--no-sandbox')
  • chrome_options.add_argument('--disable-gpu')
  • chrome_options.add_argument('--lang=zh-CN')
  • chrome_options.add_argument('--hide-scrollbars')
  • # 禁止加载图片
  • chrome_options.add_argument('blink-settings=imagesEnabled=false')
  • # 指定浏览器分辨率
  • chrome_options.add_argument('--start-maximized')
  • ssl._create_default_https_context = ssl._create_unverified_context
  • uc.TARGET_VERSION = 110 # 指定chrome版本
  • self.browser = uc.Chrome(options=chrome_options)
  • self.wait = WebDriverWait(self.browser, 10)
  • self.browser.get(self.url)
  • time.sleep(2)
  • self.browser.find_element(By.XPATH, '//*[@id="entname"]').click()
  • time.sleep(0.5)
  • self.browser.find_element(By.XPATH, '//*[@id="entname"]').clear()
  • time.sleep(0.5)
  • self.browser.find_element(By.XPATH, '//*[@id="entname"]').send_keys(self.company_name)
  • time.sleep(0.5)
  • self.browser.find_element(By.XPATH, '//*[@id="serach"]').click()
  • time.sleep(1)
  • def mk_img_dir(self):
  • """
  • 创建图片目录文件
  • :return:
  • """
  • if not os.path.exists('../national_enterprise_credit/Image'):
  • os.mkdir('../national_enterprise_credit/Image')
  • def get_geetest_image(self):
  • """
  • 获取验证码图片
  • :return: 图片location信息
  • """
  • bg = []
  • fullgb = []
  • while bg == [] and fullgb == []:
  • etree_html = etree.HTML(self.browser.page_source)
  • bg = etree_html.xpath('//div[@class="gt_cut_bg_slice"]')
  • fullgb = etree_html.xpath('//div[@class="gt_cut_fullbg_slice"]')
  • # soup = BeautifulSoup(self.browser.page_source, 'lxml')
  • # bg = soup.find_all('div', class_='gt_cut_bg_slice')
  • # fullgb = soup.find_all('div', class_='gt_cut_fullbg_slice')
  • bg_url = re.findall('url\(\"(.*?)\"\);', bg[0].get('style'))[0].replace('webp', 'jpg')
  • fullgb_url = re.findall('url\(\"(.*?)\"\);', fullgb[0].get('style'))[0].replace('webp', 'jpg')
  • bg_location_list = []
  • fullgb_location_list = []
  • for each_bg in bg:
  • location = {}
  • location['x'] = int(re.findall('background-position: (.*)px (.*)px;', each_bg.get('style'))[0][0])
  • location['y'] = int(re.findall('background-position: (.*)px (.*)px;', each_bg.get('style'))[0][1])
  • bg_location_list.append(location)
  • for each_fullgb in fullgb:
  • location = {}
  • location['x'] = int(re.findall('background-position: (.*)px (.*)px;', each_fullgb.get('style'))[0][0])
  • location['y'] = int(re.findall('background-position: (.*)px (.*)px;', each_fullgb.get('style'))[0][1])
  • fullgb_location_list.append(location)
  • self.mk_img_dir()
  • urlretrieve(url=bg_url, filename='../national_enterprise_credit/Image/bg.jpg')
  • print('缺口图片下载完成!')
  • urlretrieve(url=fullgb_url, filename='../national_enterprise_credit/Image/fullgb.jpg')
  • print('背景图片下载完成!')
  • return bg_location_list, fullgb_location_list
  • def get_merge_image(self, filename, location_list):
  • """
  • 根据图片位置合并还原
  • :param filename: 图片
  • :param location: 位置
  • :return:合并后的图片对象
  • """
  • im = Image.open(filename)
  • new_im = Image.new('RGB', (260, 116))
  • im_list_upper = []
  • im_list_lower = []
  • for location in location_list:
  • if location['y'] == -58:
  • im_list_upper.append(im.crop((abs(location['x']), 58, abs(location['x']) + 10, 116)))
  • if location['y'] == 0:
  • im_list_lower.append(im.crop((abs(location['x']), 0, abs(location['x']) + 10, 58)))
  • x_offset = 0
  • for img in im_list_upper:
  • new_im.paste(img, (x_offset, 0))
  • x_offset += img.size[0]
  • x_offset = 0
  • for img in im_list_lower:
  • new_im.paste(img, (x_offset, 58))
  • x_offset += img.size[0]
  • new_im.save('Image/' + re.split('[./]', filename)[1] + '1.jpg')
  • return new_im
  • def is_px_equal(self, img1, img2, x, y):
  • """
  • 判断两个像素是否相同
  • :param img1: 图片1
  • :param img2:图片2
  • :param x:位置1
  • :param y:位置2
  • :return:像素是否相同
  • """
  • pix1 = img1.load()[x, y]
  • pix2 = img2.load()[x, y]
  • threshold = 60
  • if abs(pix1[0] - pix2[0]) < threshold and abs(pix1[1] - pix2[1]) < threshold and abs(pix1[2] - pix2[2]) < threshold:
  • return True
  • else:
  • return False
  • def get_gap(self, img1, img2):
  • """
  • 获取缺口偏移量
  • :param img1: 不带缺口图片
  • :param img2: 带缺口图片
  • :return:
  • """
  • left = 60
  • for i in range(left, img1.size[0]):
  • for j in range(img1.size[1]):
  • if not self.is_px_equal(img1, img2, i, j):
  • left = i
  • return left
  • return left
  • def get_track(self, distance):
  • """
  • 根据偏移量和手动操作模拟计算移动轨迹
  • :param distance: 偏移量
  • :return: 移动轨迹
  • """
  • # 移动轨迹
  • tracks = []
  • # 当前位移
  • current = 0
  • # 减速阈值
  • mid = distance * 4 / 5
  • # 时间间隔
  • t = 0.2
  • # 初始速度
  • v = 0
  • while current < distance:
  • if current < mid:
  • a = random.uniform(2, 5)
  • else:
  • a = -(random.uniform(12.5, 13.5))
  • v0 = v
  • v = v0 + a * t
  • x = v0 * t + 1 / 2 * a * t * t
  • current += x
  • if 0.6 < current - distance < 1:
  • x = x - 0.53
  • tracks.append(round(x, 2))
  • elif 1 < current - distance < 1.5:
  • x = x - 1.4
  • tracks.append(round(x, 2))
  • elif 1.5 < current - distance < 3:
  • x = x - 1.8
  • tracks.append(round(x, 2))
  • else:
  • tracks.append(round(x, 2))
  • return tracks
  • def get_slider(self):
  • """
  • 获取滑块
  • :return:滑块对象
  • """
  • try:
  • slider = self.wait.until(EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_slider"]/div[contains(@class,"gt_slider_knob")]')))
  • return slider
  • except TimeoutError:
  • print('加载超时...')
  • def move_to_gap(self, slider, tracks):
  • """
  • 将滑块移动至偏移量处
  • :param slider: 滑块
  • :param tracks: 移动轨迹
  • :return:
  • """
  • action = ActionChains(self.browser)
  • action.click_and_hold(slider).perform()
  • for x in tracks:
  • action.move_by_offset(xoffset=x, yoffset=-1).perform()
  • action = ActionChains(self.browser)
  • time.sleep(0.6)
  • action.release().perform()
  • def success_check(self):
  • """
  • 验证是否成功
  • :return:
  • """
  • try:
  • if re.findall('gt_success', self.browser.page_source, re.S):
  • print('验证成功!')
  • return True
  • else:
  • print('验证失败!')
  • return False
  • except TimeoutError:
  • print('加载超时...')
  • finally:
  • time.sleep(10000)
  • # self.browser.close()
  • if __name__ == '__main__':
  • check = CrackGeetest()
  • check.chrome_operate()
  • bg_location_list, fullgb_location_list = check.get_geetest_image()
  • img1 = check.get_merge_image('Image/fullgb.jpg', fullgb_location_list)
  • img2 = check.get_merge_image('Image/bg.jpg', fullgb_location_list)
  • distance = check.get_gap(img1, img2) * 1.138
  • slider = check.get_slider()
  • tracks = check.get_track(distance)
  • print(tracks)
  • check.move_to_gap(slider, tracks)
  • # time.sleep(0.5)
  • CHECK = check.success_check()

 

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门