爬虫技术-滑块验证码
滑块验证码
1. 滑块简介
![](/assets/blank.gif)
注:重点是识别滑块缺口,测出需要拖动的距离
1.1 核心步骤
从服务器随机取一张图片,并对图片上的随机
x,y
坐标和宽高一块区域抠图;根据步骤一的坐标和宽高,使用二维数组保存原图上抠图区域的像素点坐标;
根据步骤二的坐标点,对原图的抠图区域的颜色进行处理。
完成以上步骤之后得到两张图(扣下来的方块图,带有抠图区域阴影的原图),将这两张图和抠图区域的y坐标传到前台,前端在移动方块验证时,将移动后的x坐标传递到后台与原来的x坐标作比较,如果在阈值内则验证通过。
请求验证的步骤:前台向后台发起请求,后台随机一张图片做处理将处理完的两张图片的
base64
,抠图y坐标和token
(token为后台缓存验证码的唯一token
,可以用缓存和分布式缓存)返回给前台。前台滑动图片将
x
坐标和token
作为参数请求后台验证,服务器根据token
取出x
坐标与参数的x进行比较。
1.2 突破规则
这类验证码可以使用 selenium
操作浏览器拖拽滑块来进行破解,难点两个,一个如何确定拖拽到的位置,另一个是避开人机识别(反爬虫)。
首先我们先看看,确定滑块验证码需要拖拽的位移距离
有三种方式
- 人工智能机器学习,确定滑块位置
- 通过完整图片与缺失滑块的图片进行像素对比,确定滑块位置
- 边缘检测算法,确定位置
各有优缺点。人工智能机器学习,确定滑块位置,需要进行训练比较麻烦,所以我们主要看后面两种。
对比完整图片与缺失滑块的图片
1.3 验证码图片处理
站点:https://www.geetest.com/demo/
使用浏览器技术提取滑块图片,进行处理
# 提取背景图
document.getElementsByClassName('geetest_canvas_bg geetest_absolute')[0].toDataURL('image/png')
document.getElementsByClassName('geetest_canvas_fullbg geetest_fade geetest_absolute')[0].toDataURL('image/png')# 保存图片
import base64,io
images = q_qt.split(',')[1]
images = base64.b64decode(images)
images = Image.open(io.BytesIO(images))
images.save('q_qg.png')
1.4 背景滑块识别
- 这里使用开源的技术
ddddocr
进行滑块的识别
import ddddocr
def text_dis():slide = ddddocr.DdddOcr(det=False, ocr=False)with open('bg.png', 'rb') as f:target_bytes = f.read()with open('zg.png', 'rb') as f:background_bytes = f.read()res = slide.slide_comparison(target_bytes, background_bytes)print(res)
2 OPENCV
处理滑块
opencv
是一个跨平台计算机视觉和机器学习软件库,支持Linux、windows操作系统。
一般来说,图像是一个标准的矩形,有着宽度(width)和高度(height)。而矩阵有着行(row)和列(column),矩阵的操作在数学和计算机中的处理都很常见且成熟,于是很自然的就把图像作为一个矩阵,把对图像的操作转换成对矩阵的操作,实际上所有的图像处理工具都是这么做的
2.1 cv
库讲解
2.1.1 环境安装
pip install opencv-python
运行时报错:AttributeError: partially initialized module 'cv2' has no attribute '_registerMatType' (most likely due to a circular import)
解决
原因:版本太高
解决办法:
1、首先卸载:
pip uninstall opencv-pythonpip uninstall opencv-contrib-python
2、只安装低版本的opencv-contrib-python
pip install opencv_python==3.4.10.37
使用whl
包安装
链接:https://pan.baidu.com/s/1KZd6VX-YsQjwiPoIXF1G5g
提取码:jlh1
2.2 CV
使用
2.2.1 读取图片
- 防止闪退 这个函数是在一个给定的时间内(单位ms)等待用户按键触发;如果用户没有按下 键,则接续等待(循环)
def read_img():img = cv.imread('op_test.jpg')print(img.shape)cv.imshow('image',img)cv.waitKey()
2.2.2 读取灰度
def read_img1():img = cv.imread('op_test.jpg')# 图像灰度化image = cv.cvtColor(img, cv.COLOR_BGR2GRAY)print(image.shape)cv.imshow('gray', image)cv.waitKey() # 防止闪退
2.2.3 摄像头操作
def read_video():cap = cv.VideoCapture(0) # 如果有一个摄像头就用0,大于一个用1或者其他数字cap.set(3, 640) # 设置长度,序号是3cap.set(4, 480) # 设置宽度,序号是4cap.set(10, 200) # 设置亮度,序号是10qwhile True:success, img = cap.read()if success:cv.imshow("Video", img)if cv.waitKey(1) & 0xFF == ord('q'):breakelse:cv.destroyAllWindows()break
2.3 使用cv
处理滑块
地址:https://passport.jd.com/new/login.aspx
2.3.1 处理code
from io import BytesIO
import requests
import cv2
from PIL import Image
import numpy as npdef get_dis():# 京东的滑块res = requests.get('https://iv.jd.com/slide/g.html?appId=1604ebb2287&scene=login&product=click-bind-suspend&e=PHMXTEAUGERCMBUAY2PXCENHW4KCWFS7AGHE3JYXMA4XXOOS5Z27CTBDBGC7IDQSAPSN5MT7XMVC4R5SYEPW5TJYQI&lang=zh_CN')patch = res.json().get('patch')bg = res.json().get('bg')import base64bg1 = base64.b64decode(bg)patch1 = base64.b64decode(patch)open('jd-bg1.png','wb').write(bg1)# 读取二进制图片image = np.array(Image.open(BytesIO(bg1)))gap = np.array(Image.open(BytesIO(patch1)))# 转换颜色通道,这里为什么要BGR转为RGB,因为np.array转换pillow的图像的结果就是BGR格式的image1 = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)gap1 = cv2.cvtColor(gap, cv2.COLOR_BGR2RGB)# 转为灰度图image_gray = cv2.cvtColor(image1.copy(), cv2.COLOR_BGR2GRAY)gap_gray = cv2.cvtColor(gap1.copy(), cv2.COLOR_BGR2GRAY)# 模板匹配result = cv2.matchTemplate(image_gray, gap_gray, cv2.TM_CCOEFF_NORMED)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)print(min_val, max_val, min_loc, max_loc)# 获取最大相关的x,yx, y = min_locprint(x, y)
3. 极验滑块实战
import base64
import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from urllib import request
import cv2,randomimport ddddocr
def text_dis(bg,fg):slide = ddddocr.DdddOcr(det=False, ocr=False)with open(bg, 'rb') as f:target_bytes = f.read()with open(fg, 'rb') as f:background_bytes = f.read()res = slide.slide_comparison(target_bytes, background_bytes)return res.get('target')[0]def get_slide():options = webdriver.ChromeOptions()# 对于老版本的浏览器不行options.add_argument('--disable-blink-features=AutomationControlled')driver = webdriver.Chrome(chrome_options=options)driver.maximize_window()driver.get('https://www.geetest.com/demo/slide-bind.html')# 输入框输入账号和密码driver.find_element(By.ID,'username').send_keys('13535353535')driver.find_element(By.ID,'password').send_keys('123123123')# driver.find_element(By.ID,'btn').click()time.sleep(2)driver.find_element(By.CSS_SELECTOR,'div.btn').click()time.sleep(2)img_src = driver.execute_script('return document.getElementsByClassName("geetest_canvas_bg geetest_absolute")[0].toDataURL("image/png");')im_base64 = img_src.split(',')[1]im_bytes = base64.b64decode(im_base64)with open('./bg.png', 'wb') as f:f.write(im_bytes)temp = driver.execute_script("return document.getElementsByClassName('geetest_canvas_fullbg geetest_fade geetest_absolute')[0].toDataURL('image/png');")temp_base64 = temp.split(',')[1]temp_bytes = base64.b64decode(temp_base64)with open('./temp.png', 'wb') as f:f.write(temp_bytes)distance = text_dis('bg.png', 'temp.png')# 拖动滑块slide = driver.find_element(By.CSS_SELECTOR, 'div.geetest_slider_button')action_chains = webdriver.ActionChains(driver)# 点击,准备拖拽action_chains.click_and_hold(slide)action_chains.pause(0.2)action_chains.move_by_offset(distance - 10, 0)action_chains.pause(0.8)action_chains.move_by_offset(10, 0)action_chains.pause(1.4)action_chains.move_by_offset(-10, 0)action_chains.release()action_chains.perform()time.sleep(20)get_slide()'''
2、鼠标操作
click --- 鼠标左键点击(可以指定或不指定元素对象)
click_and_hold --- 鼠标左键点击但不释放(可以指定或不指定元素对象)
release --- 释放鼠标点击动作(可以指定或不指定在目标元素对象上释放)
context_click --- 鼠标右键点击(可以指定或不指定元素对象)
double_click --- 鼠标左键双击(可以指定或不指定元素对象)
drag_and_drop --- 鼠标左键在两个元素之间拖拽
drag_and_drop_by_offset --- 鼠标左键拖拽元素到目标偏移位置
move_by_offset --- 鼠标移动指定偏移
move_to_element --- 鼠标移动到指定元素
move_to_element_with_offset --- 鼠标移动到指定元素的指定偏移位置1、行为控制
perform --- 执行所有准备好的Action
reset_actions --- 清空所有准备好的Action # 该方法在 selenium 3.141.0版本不生效
pause --- 设置Action之间的动作时间间隔'''
爬虫技术-滑块验证码相关推荐
- java爬虫破解滑块验证码
使用技术:java+Selenium 废话: 有爬虫,自然就有反爬虫,就像病毒和杀毒软件一样,有攻就有防,两者彼此推进发展.而目前最流行的反爬技术验证码,为了防止爬虫自动注册,批量生成垃圾账号,几乎所 ...
- python爬虫进阶-滑块验证码破解(bilibili)
目标 如下图,利用selenium模拟拖动滑块完成验证 关键问题 我们知道selenium可以定位到用户名和密码,用send_keys可以实现输入账号密码.同样我们可以用selenium定位到滑块,用 ...
- APP爬虫过滑块验证码的一种思路, 从此不再依赖打码平台
每一个想学习的念头,都有可能是未来的你在向自己求救. 最近在学习 APP 逆向的道路上遇到一个 APP,当请求接口频繁的时候,会触发风控提示需要滑动验证码.验证码类型/风格类似下图: 经过分析发现,当 ...
- 网络爬虫-tx滑块验证码
仅供研究学习使用. 目标站点 --> 腾讯防水墙官网 首先打开Fiddler,刷新下页面完成一组操作,发现主要请求有这几个 去除加载的js与log上传,真正的一组操作有三个: 1是初始化验证码. ...
- 抖音web爬虫【滑块验证码解决方法】
文章内容仅供参考学习,如有侵权请联系作者进行删除 实现过程: 1.通过node下载滑块的图片 2.通过python的cv2视觉识别图对图片进行定位位置 3.通过获取的位置再通过node的控制鼠标自动移 ...
- 反爬虫技术及解决方案
不同类型的网站都有不一样的反爬虫机制,判断一个网站是否有反爬虫机制需要根据网站设计架构.数据传输方式和请求方式等各个方面评估.下面是常用的反爬虫机制. 用户请求的Headers. 用户操作网站行为. ...
- 网络爬虫-破解顶象滑块验证码
仅供研究学习使用. 今天带来的是dx滑块验证码的逆向 目标站 --> 传送门 解决此类验证码 首先要解决滑动距离的判定 无论是使用selenium还是使用协议的方式来破解 都绕不开滑动距离的识别 ...
- 了解一下爬虫技术方方面面
本文全面的介绍了爬虫的原理.技术现状.以及目前仍面临的问题.如果你没接触过爬虫,本文很适合你,如果你是一名资深的虫师,那么文末的彩蛋你可能感兴趣. 一.需求 万维网上有着无数的 ...
- Python Selenium破解滑块验证码最新版!
通过率高达百分之95!真的强! 一.滑块验证码简述 有爬虫,自然就有反爬虫,就像病毒和杀毒软件一样,有攻就有防,两者彼此推进发展.而目前最流行的反爬技术验证码,为了防止爬虫自动注册,批量生成垃圾账号, ...
最新文章
- 将调用密集型的 COM 组件迁移到托管代码
- MySQL/InnoDB处理AUTO_INCREMENT(二)
- PHP学习笔记-字符串操作1
- Spring学习笔记--spring+mybatis集成
- SQL SERVER 存储过程执行带输出参数的SQL语句拼接
- 【问题记录】raise IndexError(‘index {} is out of range‘.format(idx)) index 0 is out of range
- Scala _07trait特性
- TIDB事务过大transction too large解决方法
- 极限学习机ELM原理与实现
- 第1期——WLAN定义和基本架构
- cmd 如何打开资源管理器
- python手势识别算法_Hand-gesture-recognition 这是一个用python写的手势识别的算法 - 下载 - 搜珍网...
- 【C++】模板特化、偏特化
- 联盛德W806入门教程-CDK安装教程及代码下烧录
- JDK、JER、JVM是什么
- 企业资金链断裂如何表现在现金流量表中?看净现金流量吗?
- 我可能永远也没办法成为全栈工程师了,看看你还差多少?
- 计算机的工作原理是二进制原理吗,计算机是怎么通过二进制原理来工作的?
- 你必须跌到你从未经历过的谷底,才能站上你从未到达过的高峰
- enum 泛型 java_Java Enum作为Enum中的泛型类型