list @size 验证_python爬虫21 | 对于b站这样的滑动验证码,不好意思,照样自动识别...
今天
要来说说滑动验证码了
大家应该都很熟悉
点击滑块然后移动到图片缺口进行验证
现在越来越多的网站使用这样的验证方式
为的是增加验证码识别的难度
那么
对于这种验证码
应该怎么破呢
接下来就是
学习 python 的正确姿势
打开 b 站的登录页面
https://passport.bilibili.com/login
可以看到登录的时候需要进行滑块验证
按下 F12
进入 Network
看下我们将滑块移到缺口松开之后做了什么提交
可以看到是一个 GET 请求
但是
这请求链接也太特么长了吧
就是比小帅b短了一点点
我们来看看请求的参数是怎么样的
哇靠
gt?
challenge?
w?
这些都是什么鬼参数
还加密了
完全下不了手啊
那么
本篇完
再见
peace
说
你是不是迷恋我??
好吧
你居然滑到这里来了
说明你还是有点爱小帅b的
小帅b是那种遇到一点困难就放弃的人吗
显然不是
那么接下来才是真的
学习 python 的正确姿势
既然以请求的方式不好弄
我们从它们的源代码入手
看看有什么突破口
回到 b 站的登录页
按下 F12
进入 Element
然后点击滑块出现了图片
定位一下
发现有两个 a 标签
一个 class 是 gt_bg gt_show
一个 class 是 gt_fullbg gt_show
和小帅b想的一样
这个验证码应该是有两张图片
一张是完全的背景图片
一张是缺口的图片
那把这两张图片下载下来对比一下不就行了
打开 a 标签一看
哇靠
一张图片被切割成很多小块
原来这张图片是拼出来的
我们看看原始图片是怎么样的
什么乱七八糟的
再仔细看下源代码
原来是在同一张图片通过偏移量合成了一张完整的图片
background-position: -277px -58px;
厉害厉害
小帅b看了一下缺口的图片也是如此
到这里
我们的第一个思路就是
下载这两张原始图片
然后通过偏移量合成两张真正的图片
背景图
↓变身
缺口图
↓变身
那么怎么做呢?
因为我们还要模拟滑动滑块
所以呢
我们要用到 selenium
打开b站的登录页
然后等到那个滑块显示出来
# 获取滑块按钮driver.get(url)slider = WAIT.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#gc-box > div > div.gt_slider > div.gt_slider_knob.gt_show")))
接下来我们就获取页面的源码
driver.page_source
然后使用 bs 获取两张原始背景图片的 url
bs = BeautifulSoup(driver.page_source,'lxml')# 找到背景图片和缺口图片的divbg_div = bs.find_all(class_='gt_cut_bg_slice')fullbg_div = bs.find_all(class_='gt_cut_fullbg_slice')
# 获取缺口背景图片urlbg_url = re.findall('background-image:surl("(.*?)")',bg_div[0].get('style'))# 获取背景图片urlfullbg_url = re.findall('background-image:surl("(.*?)")',fullbg_div[0].get('style'))
拿到了图片地址之后
将图片下载下来
# 将图片格式存为 jpg 格式bg_url = bg_url[0].replace('webp', 'jpg')fullbg_url = fullbg_url[0].replace('webp', 'jpg')# print(bg_url)# print(fullbg_url)
# 下载图片bg_image = requests.get(bg_url).contentfullbg_image = requests.get(fullbg_url).contentprint('完成图片下载')
ok
我们已经把两张原始图片下载下来了
那么接下来就是要合成图片了
我们要根据图片的位置来合成
也就是源码中的 background-position
获取每一个小图片的位置
我们可以通过字典的形式来表示这些位置
然后将数据放到列表中
# 存放每个合成缺口背景图片的位置bg_location_list = []# 存放每个合成背景图片的位置fullbg_location_list = []
for bg in bg_div:location = {}location['x'] = int(re.findall('background-position:s(.*?)pxs(.*?)px;', bg.get('style'))[0][0])location['y'] = int(re.findall('background-position:s(.*?)pxs(.*?)px;', bg.get('style'))[0][1])bg_location_list.append(location)
for fullbg in fullbg_div:location = {}location['x'] = int(re.findall('background-position:s(.*?)pxs(.*?)px;', fullbg.get('style'))[0][0])location['y'] = int(re.findall('background-position:s(.*?)pxs(.*?)px;', fullbg.get('style'))[0][1])fullbg_location_list.append(location)
那么
现在我们已经有了原始图片
还知道了每个位置应该显示原始图片的什么部分
接下来我们就写一个方法
用来合成图片
# 写入图片bg_image_file = BytesIO(bg_image)fullbg_image_file = BytesIO(fullbg_image)
# 合成图片bg_Image = mergy_Image(bg_image_file, bg_location_list)fullbg_Image = mergy_Image(fullbg_image_file, fullbg_location_list)
那么问题又来了
怎么合成啊
我们再看看一开始分析的图片
这里图片被分割成的每一个小图片的尺寸是
10 * 58
所以我们也要将我们刚刚下载的原始图片切割成相应的尺寸大小
而且
这张图片是由上半部分的小图片和下半部分的小图片合成的
所以我们定义两个 list 来装这些小图片
# 存放上下部分的各个小块upper_half_list = []down_half_list = []
然后将原始的图片切割好放进去
image = Image.open(image_file)
# 通过 y 的位置来判断是上半部分还是下半部分,然后切割for location in location_list:if location['y'] == -58:# 间距为10,y:58-116im = image.crop((abs(location['x']), 58, abs(location['x'])+10, 116))upper_half_list.append(im)if location['y'] == 0:# 间距为10,y:0-58im = image.crop((abs(location['x']), 0, abs(location['x']) + 10, 58))down_half_list.append(im)
至此
我们这两个 list 就分别放好了各个切割的图片了
那么接下来就创建一张空白的图片
然后将小图片一张一张(间距为10)的粘贴到空白图片里
这样我们就可以得到一张合成好的图片了
哎
我真是个天才
# 创建一张大小一样的图片new_image = Image.new('RGB', (260, 116))
# 粘贴好上半部分 y坐标是从上到下(0-116)offset = 0for im in upper_half_list:new_image.paste(im, (offset, 0))offset += 10
# 粘贴好下半部分offset = 0for im in down_half_list:new_image.paste(im, (offset, 58))offset += 10
那么到现在
我们可以得到网页上显示的那两张图片了
一张完全的图片
一张带缺口的图片
接下来我们就要通过对比这两张图
看看我们要滑动的距离是多远
# 合成图片bg_Image = mergy_Image(bg_image_file, bg_location_list)fullbg_Image = mergy_Image(fullbg_image_file, fullbg_location_list)# bg_Image.show()# fullbg_Image.show()
# 计算缺口偏移距离distance = get_distance(bg_Image, fullbg_Image)print('得到距离:%s' % str(distance))
可以通过图片的 RGB 来计算
我们设定一个阈值
如果 r、g、b 大于这个阈值
我们就返回距离
def get_distance(bg_Image, fullbg_Image):
#阈值threshold = 200
print(bg_Image.size[0])print(bg_Image.size[1])
for i in range(60, bg_Image.size[0]):for j in range(bg_Image.size[1]):bg_pix = bg_Image.getpixel((i, j))fullbg_pix = fullbg_Image.getpixel((i, j))r = abs(bg_pix[0] - fullbg_pix[0])g = abs(bg_pix[1] - fullbg_pix[1])b = abs(bg_pix[2] - fullbg_pix[2])
if r + g + b > threshold:return i
现在
我们知道了关键的滑动距离了
激动人心的时刻到了
我们使用 selenium
拿到滑块的元素
然后根据这个距离拖动到缺口位置不就好了么
马上打开 selenium 的文档
看到了这个函数
它可以使用左键点击元素
然后拖动到指定距离
最后释放鼠标左键
挖槽
正合我意
赶紧试一下
knob = WAIT.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#gc-box > div > div.gt_slider > div.gt_slider_knob.gt_show")))
ActionChains(driver).drag_and_drop_by_offset(knob, distance, 0).perform()
运行一下试试看吧
哇哦你妹哦~
妖怪吃了拼图了
看来直接拖拽是不行的
容易遇到妖怪
毕竟这太快了
就算加藤鹰也没那么快吧
小帅b试着拖完滑块让它睡一下再释放
ActionChains(driver).click_and_hold(knob).perform()ActionChains(driver).move_by_offset(xoffset=distance, yoffset=0.1).perform()time.sleep(0.5)ActionChains(driver).release(knob).perform()
发现拼图还是特么的被妖怪吃了
后来小帅b发现原来别人也遇到了这样的问题
然后又发现了
有个叫匀速直线运动的东西
什么 加速度
什么 v = v0 + at
什么 s = ½at²
哇
这不是高中的知识点么
瞬间想起小帅b高中的时候在最角落的课桌
此刻往右上方抬起头
45 度角
让我的眼泪划出一条美丽的弧线
什么鬼
回到正题
我们可以使用它来构造一个运动路径
该加速时加速
该减速的时候减速
这样的话就更像人类在滑动滑块了
def get_path(distance):result = []current = 0mid = distance * 4 / 5t = 0.2v = 0while current < (distance - 10):if current < mid:a = 2else:a = -3v0 = vv = v0 + a * ts = v0 * t + 0.5 * a * t * tcurrent += sresult.append(round(s))return result
这次
我们使用这个轨迹来滑动
knob = WAIT.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#gc-box > div > div.gt_slider > div.gt_slider_knob.gt_show")))result = get_path(distance)ActionChains(driver).click_and_hold(knob).perform()
for x in result:ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()
time.sleep(0.5)ActionChains(driver).release(knob).perform()
好了好了
我们再来运行一下吧
哈哈哈
cool
成功识别了哇
我不管
当然了
成功率不是 100%
可以多调戏它几次
ok
以上就是识别滑动验证码的具体过程了
对于其它大部分的滑动验证码
也是可以使用这招搞定的
由于篇幅有限
源代码我放在了这个公众号【学习python的正确姿势】后台了
你发送〔滑动〕两个字
就可以获取啦
那
这次本篇就真的完啦
听说你想约我?
peace
肯定会
相关文章
(小帅b教你三招搞定模拟登录)
(小帅b教你轻松识别图片验证码)
点个在zan啊~~(破音)
list @size 验证_python爬虫21 | 对于b站这样的滑动验证码,不好意思,照样自动识别...相关推荐
- python爬虫滑动验证码_python爬虫21 | 对于b站这样的滑动验证码,不好意思,照样自动识别...
今天 要来说说滑动验证码了 大家应该都很熟悉 点击滑块然后移动到图片缺口进行验证 现在越来越多的网站使用这样的验证方式 为的是增加验证码识别的难度 那么 对于这种验证码 应该怎么破呢 接下来就是 打开 ...
- float js 正则 验证_爬虫篇 | 200 行代码实现一个滑动验证码
最近整理一个爬虫系列方面的文章,不管大家的基础如何,我从头开始整一个爬虫系列方面的文章,让大家循序渐进的学习爬虫,小白也没有学习障碍. 爬虫篇 | Python使用正则来爬取豆瓣图书数据 爬虫篇 | ...
- 爬虫学习笔记(十九)—— 滑动验证码
文章目录 一.概念 二.实现步骤 2.1.获取验证码图片 2.1.1.获取缺口图 2.1.2.获取滑块图 2.1.3.获取完整图 2.1.4.完整代码 2.2.计算缺口位置 2.3.模拟人工移动 2. ...
- python 代理ip验证_python爬虫成长之路(二):抓取代理IP并多线程验证
上回说到,突破反爬虫限制的方法之一就是多用几个代理IP,但前提是我们得拥有有效的代理IP,下面我们来介绍抓取代理IP并多线程快速验证其有效性的过程. 一.抓取代理IP 提供免费代理IP的网站还挺多的, ...
- 复制url直接能跳过验证_python 爬虫如何突破登录验证
我用 python 做爬虫爬过不少数据,比如在 google play 爬应用信息:在 instragram, 500px 爬图片:当然爬虫的作用不止于此,比如定时去某个网站签到,妈妈再也不用担心我忘 ...
- python b站 排行_Python爬虫抓取B站小视频排行榜,新手也可以跟着做哦!
Python爬虫学到什么程度就可以去找工作了? 有朋友在群里和大家讨论,问的最多的问题就是,python 爬虫学到什么程度可以去找工作了,关于这点,和大家分享下我的理解. 看大牛用Python实现发送 ...
- struts2的登录注册 验证码 邮箱验证_Python+tkinter模拟京东登录时拖动图片式验证码...
好消息:"Python小屋"编程比赛正式开始 推荐图书: <Python程序设计(第3版)>,(ISBN:978-7-302-55083-9),董付国,清华大学出版社, ...
- Python爬虫的实际运用之:破解滑动验证码
做爬虫总会遇到各种各样的反爬限制,反爬的第一道防线往往在登录就出现了,为了限制爬虫自动登录,各家使出了浑身解数,所谓道高一尺魔高一丈. 今天分享个如何简单处理滑动图片的验证码的案例. 类似这种拖动滑块 ...
- python获取登录按钮_python爬虫24 | 搞事情了,用 Appium 爬取你的微信朋友圈
昨天小帅b看到一些事情不顺眼 有人偷换概念 忍不住就写了一篇反讽 996 的 看不下去了,我支持996,年轻人就该996! 没想到有些人看不懂 这就算了 还来骂我 早些时候关注我的小伙伴应该知道我第 ...
最新文章
- AI如果耍起了心眼,人类就像个白痴......
- python和linux哪个难学-“慢”下来的 Python 要怎么竞争?
- 关于微信小程序的尺寸关系
- 使用Callable和Future接口创建线程
- 刨根问底——Handler
- flashback_transaction_query查询权限
- mysql插入日期 vs oracle插入日期
- HDU——1054 Strategic Game
- python大于小于_在Python中大于/小于Pandas DataFrames / Series之间的比较
- [蓝桥杯2018初赛]分数-找规律
- 当字段过长,鼠标移上去才展示全部,默认只展示部分防止表格比例发生变化
- MATLAB字符串和ASCII码的转换
- 数学建模matlab推荐,推荐数学建模matlab方法整理 - 图文
- 【Elasticsearch】Elasticsearch analyzer 中文 分词器
- 拓端tecdat|自然语言处理NLP:主题LDA、情感分析疫情下的新闻文本数据
- postgre数据库记录唯一键_详解sqlserver数据库的索引设计
- mysql pxc缺点_MYSQL高可用之PXC
- redis介绍命令性能数据及监控缓存穿透
- 梦幻手游服务器维护摆摊公示时间,梦幻西游手游5月27日维护公告
- BrupSuite Repeater模块
热门文章
- 【庖丁解牛】Abort class-pclzip.php : Missing zlib extensions
- 【庖丁解牛】图像处理库: 解决WeCenter至少需要有GD图像处理库才能正常运行
- Latex 图标题过长不能跨页显示解决办法,Figure caption does not continue on new page
- sql 截取json数据_PostgreSQL 12 新特性解读之一|支持 SQL/JSON path
- ZXING 二维码扫描
- pagehelper pagesize获取不到_Spring Boot 2.x(十三):你不知道的PageHelper
- 益和VA 虚拟化应用安全性深度体验
- python sequence_干货来袭!Python高阶函数使用总结~
- Python爬虫笔记——多线程(threading)传参
- 鲁大师智慧电动车排行:小牛“高光”不再,产品力下降是主因?