1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 破解验证码(2)滑动验证码

破解验证码(2)滑动验证码

时间:2018-11-04 06:28:03

相关推荐

破解验证码(2)滑动验证码

前言

做爬虫时,难免会遇到需要通过验证码才能访问网址进行爬取内容,所以需要额外掌握破解验证码的技巧才行。

本文将讲解另一个验证码示例来进行演示(滑动验证码

上一篇写了: 破解验证码(1)数字英文验证码,可跳转到:/ytraister/article/details/106307610

实例

以腾讯防水墙滑动验证码为例,进行破解python + selenium + cv2验证码地址:https://open./online.html使用OpenCV库,需要额外安装:pip install opencv-python效果如下图:

》完整代码如下(含解析):

实际开发中,可以根据自己的需求进行改动

import numpy as np# 矩阵计算的函数库import randomfrom selenium.webdriver import ActionChains# 控制鼠标操作import timefrom selenium import webdriverfrom PIL import Image # Python图像库import osfrom selenium.webdriver.support.ui import WebDriverWaitimport cv2 # 强大的图像处理和计算机视觉库class Login(object):def __init__(self):# 初始化方法:url、driver(浏览器驱动)# 如果是实际应用中,可在此处添加账号和密码self.url = "https://open./online.html"self.driver = webdriver.Chrome()@staticmethoddef show(name):# 调用窗口显示图片,以下3步骤是必须的cv2.imshow("Show", name) # 参数1:窗口名称;参数2:需要显示的图片cv2.waitKey(0)cv2.destroyAllWindows()@staticmethoddef webdriverwait_send_keys(dri, element, value):"""显示等待 输入:param dri:浏览器驱动driver:param element: 通过selenium获取到的html元素:param value: 需要传入的值"""WebDriverWait(dri, 10, 5).until(lambda dr: element).send_keys(value)@staticmethoddef webdriverwait_click(dri, element):"""显示等待 click:param dri:浏览器驱动driver:param element: 通过selenium获取到的html元素"""WebDriverWait(dri, 10, 5).until(lambda dr: element).click()# 当需要多次调用该显示等待函数时,可以使用匿名函数lambda来获取元素lambda函数接收一个参数word(即上面的dr)。且在冒号和末尾圆括号之间的部分为函数的定义。@staticmethoddef get_position(chunk, canves):"""判断缺口位置:param chunk: 缺口图片(验证码中的大图):param canves: 验证码中的拼图:return: 位置 x, y"""# cv2.imread()用于读取图片文件;参数1:图片路径,参数2:读取图片的形式(1表示彩色图片[默认],0表示灰度图片,-1表示原来的格式)chunk = cv2.imread(chunk, 0) # 读取大图(灰化)canves = cv2.imread(canves, 0)# 读取拼图(灰化)# 二值化后的图片名称slide_puzzle = "slide_puzzle.jpg"slide_bg = "slide_bg.jpg"# 将二值化后的图片进行保存# cv2.imwrite()用于保存图片文件;参数1:保存的图像名称,参数2:需要保存的图像cv2.imwrite(slide_bg, chunk) # 保存大图cv2.imwrite(slide_puzzle, canves) # 保存拼图chunk = cv2.imread(slide_bg) # 使用cv2.imread()读出来的是BGR数据格式# cv2.cvtColor(p1, p2) 是颜色空间转换函数 参数1:需要转换的图片,参数2:转换成何种格式# cv2.COLOR_BGR2RGB:将BGR格式转换成RGB格式cv2.COLOR_BGR2GRAY:将BGR格式转换成灰度图片chunk = cv2.cvtColor(chunk, cv2.COLOR_BGR2GRAY)chunk = abs(255 - chunk)# abs用于返回数字的绝对值cv2.imwrite(slide_bg, chunk) # 保存大图 此时大图缺口部分的颜色比较浅,图像较容易识别到该缺口部分chunk = cv2.imread(slide_bg) # 读取大图canves = cv2.imread(slide_puzzle) # 读取拼图# 获取偏移量result = cv2.matchTemplate(chunk, canves, cv2.TM_CCOEFF_NORMED) # cv2.matchTemplate()实现模板匹配(即用来在大图中找小图,也就是说在一副图像中寻找另外一张模板图像的位置)# 返回的result是一个矩阵,是每个点的匹配结果# Login.show(chunk) # 展示大图二值化后的效果# result.argmax()返回的是矩阵中最大数值的下标; result.shape 返回的是(680, 390)即下载的图片对象的尺寸y, x = np.unravel_index(result.argmax(), result.shape)# np.unravel_index()作用:获取一个/组 int类型的索引值在一个多维数组中的位置 计算出 大图 与 拼图 位移的距离return x # 实际滑动的距离就是x轴的距离,因此只需要x的值即可@staticmethoddef get_track(distance):"""模拟轨迹 假装是人在操作匀变速运动基本公式:①v=v0+at 速度公式②s=v0t+(1/2)at²位移公式:param distance: 移动的距离:return: track"""v = 0 # 初速度t = 0.2 # 时间间隔0.2stracks = [] # 移动轨迹列表,列表内的每一个元素代表0.2s的位移current = 0 # 当前的位移mid = distance * 4 / 5# 到达mid值开始减速(前4/5段加速 后1/5段减速)distance += 10 # 先滑过一点,最后再反着滑动回来while current < distance:if current < mid:# 加速度越小,单位时间的位移越小,模拟的轨迹就越多越详细a = random.randint(28, 30)# 加速运动else:a = -random.randint(12, 13)# 减速运动v0 = v# 初速度s = v0 * t + 0.5 * a * (t ** 2)# 0.2秒时间内的位移current += s # 当前的位置tracks.append(round(s)) # 添加到轨迹列表,round()为保留一位小数且该小数要进行四舍五入v = v0 + a * t # 速度已经达到v,该速度作为下次的初速度# 反着滑动到大概准确位置for i in range(4):tracks.append(-random.randint(3, 4))return tracks@staticmethoddef urllib_download(imgurl, imgsavepath):"""下载图片:param imgurl:需要下载图片的url:param imgsavepath: 图片存放位置"""# python3中的urllib.request模块所提供的urlretrieve()函数。urlretrieve()方法可以直接将远程数据下载到本地from urllib.request import urlretrieveurlretrieve(imgurl, imgsavepath)def after_quit(self):"""关闭浏览器"""self.driver.quit()def login_main(self):# ssl._create_default_https_context = ssl._create_unverified_context # 用于忽略网页的SSL认证,需要额外导入import ssldriver = self.driverdriver.maximize_window()driver.get(self.url)# 获取到元素并实现点击click_keyi_username = driver.find_element_by_xpath("//div[@class='wp-onb-tit']/a[text()='可疑用户']")self.webdriverwait_click(driver, click_keyi_username)login_button = driver.find_element_by_id('code')self.webdriverwait_click(driver, login_button)time.sleep(1)driver.switch_to.frame(driver.find_element_by_id('tcaptcha_iframe')) # 用于获取到验证码iframe元素time.sleep(0.5)bk_block = driver.find_element_by_xpath('//img[@id="slideBg"]') # 获取验证码中的大图web_image_width = bk_block.size # 获取大图的大小(高度、宽度)web_image_width = web_image_width['width'] # 获取大图的宽度# print(bk_block.location) # 该图片对象在弹出的验证码框中的位置,返回字典的格式,例如:{'x': 10, 'y': 61}bk_block_x = bk_block.location['x'] # 获取该图片对象在验证码框中的位置(x轴)slide_block = driver.find_element_by_xpath('//img[@id="slideBlock"]') # 获取验证码中的拼图# print(bk_block.location) # 该图片对象在弹出的验证码框中的位置,返回字典的格式,例如:{'x': 36, 'y': 102}slide_block_x = slide_block.location['x'] # 获取该图片对象在验证码框中的位置(x轴)bk_block = driver.find_element_by_xpath('//img[@id="slideBg"]').get_attribute('src') # 获取验证码中的大图urlslide_block = driver.find_element_by_xpath('//img[@id="slideBlock"]').get_attribute('src') # 获取验证码中的拼图urlslid_ing = driver.find_element_by_xpath('//div[@id="tcaptcha_drag_thumb"]') # 获取滑块os.makedirs('./image/', exist_ok=True)# os.makedirs():递归创建多层目录;其中参数exist_ok=True:表示在目标目录已存在的情况下不会抛出异常(即不会报错)self.urllib_download(bk_block, './image/bkBlock.png') # 下载验证码中的大图self.urllib_download(slide_block, './image/slideBlock.png')# 下载验证码中的拼图time.sleep(0.5)img_bkblock = Image.open('./image/bkBlock.png') # 因为下载的大图跟浏览器中显示的大图比例不一样,会影响到滑动的距离跟速度,所以计算出比例后面用到real_width = img_bkblock.size[0] # 获取下载的验证码中大图的宽度:680width_scale = float(real_width) / float(web_image_width) # 得出比例[下载的大图大小为:680*390;浏览器显示的大图大小为:340.81*198.45(大概)]position_x = self.get_position('./image/bkBlock.png', './image/slideBlock.png')# 获取到 大图 与 拼图 位移的距离 (实际滑动的距离就是x轴的距离)real_position = position_x / width_scale # 将大图/比例,得到验证码框中大图与拼图实际的滑动距离real_position = real_position - (slide_block_x - bk_block_x) # (slide_block_x - bk_block_x):即拼图到大图的左边距,所以减去左边距后才得到真正的滑动距离track_list = self.get_track(real_position) # 调用get_track()方法,传入真实距离参数,得出移动轨迹ActionChains(driver).click_and_hold(on_element=slid_ing).perform() # 找到滑块元素,点击鼠标左键,按住不放time.sleep(0.2)# 拖动元素for track in track_list:ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform()# 根据运动轨迹(x轴),进行拖动time.sleep(0.002)time.sleep(1)ActionChains(driver).release(on_element=slid_ing).perform()# 释放鼠标time.sleep(1)print('登录成功')self.after_quit()if __name__ == '__main__':login = Login()login.login_main()

》参考文献:

/qq_38534107/article/details/89522481

/Tracy_LeBron/article/details/84567419

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。