python selenium模拟滑动验证码
2019-04-03 09:16
477 查看
此文以B站模拟登录,滑动验证码的测试。
import random import time import requests from selenium.webdriver import ActionChains from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from urllib.request import urlretrieve from selenium import webdriver from bs4 import BeautifulSoup import PIL.Image as image import re class Crack(): def __init__(self, username, passwd): self.url = 'https://passport.bilibili.com/login' self.browser = webdriver.Chrome() self.wait = WebDriverWait(self.browser, 100) self.BORDER = 6 self.passwd = passwd self.username = username def open(self): """ 打开浏览器,并输入查询内容 """ self.browser.get(self.url) keyword = self.wait.until(EC.presence_of_element_located((By.ID, 'login-username'))) keyword.send_keys(self.username) keyword = self.wait.until(EC.presence_of_element_located((By.ID, 'login-passwd'))) keyword.send_keys(self.passwd) # bowton.click() def get_images(self, bg_filename='bg.jpg', fullbg_filename='fullbg.jpg'): """ 获取验证码图片 :return: 图片的location信息 """ bg = [] fullgb = [] while bg == [] and fullgb == []: bf = BeautifulSoup(self.browser.page_source, 'lxml') bg = bf.find_all('div', class_='gt_cut_bg_slice') fullgb = bf.find_all('div', class_='gt_cut_fullbg_slice') print(bg[0].get('style')) 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 = [] fullbg_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]) fullbg_location_list.append(location) # 把资源下载到临时目录 headers = {'User-Agent': 'Mozilla/5.0 (compatible; WOW64; MSIE 10.0; Windows NT 6.2)'} #urlretrieve(url=bg_url, filename=bg_filename) with open(bg_filename,'wb') as file: file.write(requests.get(url=bg_url,headers=headers).content) print('缺口图片下载完成') #urlretrieve(url=fullgb_url, filename=fullbg_filename) with open(fullbg_filename,'wb') as file: file.write(requests.get(url=fullgb_url,headers=headers).content) print('背景图片下载完成') return bg_location_list, fullbg_location_list def get_merge_image(self, filename, location_list): """ 根据位置对图片进行合并还原 :filename:图片 :location_list:图片位置 """ im = image.open(filename) new_im = image.new('RGB', (260, 116)) im_list_upper = [] im_list_down = [] for location in location_list: if location['y'] == -58: im_list_upper.append(im.crop((abs(location['x']), 58, abs(location['x']) + 10, 166))) if location['y'] == 0: im_list_down.append(im.crop((abs(location['x']), 0, abs(location['x']) + 10, 58))) new_im = image.new('RGB', (260, 116)) x_offset = 0 for im in im_list_upper: new_im.paste(im, (x_offset, 0)) x_offset += im.size[0] x_offset = 0 for im in im_list_down: new_im.paste(im, (x_offset, 58)) x_offset += im.size[0] new_im.save(filename) return new_im def is_pixel_equal(self, img1, img2, x, y): """ 判断两个像素是否相同 :param image1: 图片1 :param image2: 图片2 :param x: 4000 位置x :param y: 位置y :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 = 43 for i in range(left, img1.size[0]): for j in range(img1.size[1]): if not self.is_pixel_equal(img1, img2, i, j): left = i return left return left def get_track(self, distance): """ 根据偏移量获取移动轨迹 :param distance: 偏移量 :return: 移动轨迹 """ # 移动轨迹 track = [] # 当前位移 current = 0 # 减速阈值 mid = distance * 0.7 # 计算间隔 t = 0.05 # 初速度 v = 0 while current < distance: if current < mid: # 加速度为正2 a = 18 else: # 加速度为负3 a = -6 # 初速度v0 v0 = v # 当前速度v = v0 + at v = v0 + a * t # 移动距离x = v0t + 1/2 * a * t^2 move = v0 * t + 1 / 2 * a * t * t # 当前位移 current += move # 加入轨迹 track.append(round(move)) print('forword', current, distance) v = 0 move = current - distance # 加入轨迹 track.append(round(move)) return track def get_slider(self): """ 获取滑块 :return: 滑块对象 """ while True: try: slider = self.browser.find_element_by_xpath("//div[@class='gt_slider_knob gt_show']") break except: time.sleep(0.5) return slider def move_to_gap(self, slider, track): """ 拖动滑块到缺口处 :param slider: 滑块 :param track: 轨迹 :return: """ ActionChains(self.browser).click_and_hold(slider).perform() while track: x = random.choice(track) #x=track.pop(0) ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform() track.remove(x) time.sleep(0.01) time.sleep(2) print('release') ActionChains(self.browser).release(slider).perform() time.sleep(2) #self.browser.quit() def crack(self): # 打开浏览器 self.open() # 保存的图片名字 bg_filename = './images/bg.jpg' fullbg_filename = './images/fullbg.jpg' # 获取图片 bg_location_list, fullbg_location_list = self.get_images(bg_filename, fullbg_filename) # 根据位置对图片进行合并还原 bg_img = self.get_merge_image(bg_filename, bg_location_list) fullbg_img = self.get_merge_image(fullbg_filename, fullbg_location_list) # 获取缺口位置 gap = self.get_gap(fullbg_img, bg_img) print('缺口位置', gap) track = self.get_track(gap - self.BORDER) print('滑动滑块') #print(track) # 点按呼出缺口 slider = self.get_slider() # 拖动滑块到缺口处 self.move_to_gap(slider, track) # time.sleep(1) try: mspan = self.browser.find_elements_by_class_name('gt_info_content') if len(mspan) > 0: info = mspan.text print('info:',info) if '怪物吃了拼图' in info: print(mspan.text) time.sleep(2) self.crack() mspan = self.browser.find_elements_by_class_name('gt_info_type') if len(mspan) > 0: info = mspan[0].text print('info:', info) if '验证失败:' in info: time.sleep(2) self.crack() except Exception as e: print(e) if __name__ == '__main__': crack = Crack('username', 'passwd') crack.crack() print('验证成功')
相关文章推荐
- python selenium的模拟点击,模拟滑动等操作
- 滑动验证码的破解(python+opencv+selenium)
- Python中Selenium模拟JQuery滑动解锁实例
- webdriver 验证码问题 selenium_python
- Python爬虫-尝试使用人工和OCR处理验证码模拟登入
- python之selenium模拟登录知乎
- Python爬虫之selenium爬虫,模拟浏览器爬取天猫信息
- Python爬虫(二十三)_selenium案例:动态模拟页面点击
- Python Selenium Cookie 绕过验证码实现登录
- python+chrome+Selenium模拟手机浏览器
- Java selenium处理极验滑动验证码示例
- python模拟登陆“春秋航空”官网+手动输入验证码
- Python+selenium通过设置Cookie绕过验证码登录。
- selenium+java破解极验滑动验证码
- selenium+java破解极验滑动验证码的示例代码
- 基于Python的Selenium自动化(3)— 实现验证码截取并识别
- selenium+python模拟登陆163邮箱
- python之selenium模拟登录微博
- Selenium+Python对开源中国官网进行模拟登录