爬虫时遇到滑动验证,基本思路是通过selenium操作浏览器,将滑动验证的原始图片和缺口图片进行对比,找出缺口位置,然后在利用selenium模拟拖动滑块,达到验证的目的。下面就以猪八戒网为例,进行操作。

一、分析

首先访问 https://account.zbj.com/login:

登陆页面主要为上图。

点击按钮(div标签,类名为 geetest_radar_tip)后,出现滑动验证码:

这个滑动验证图片并没有原始图片,直接出现的就是缺口图片。而我们要找的就是深色缺口的位置。

观察图片标签,找到 这个标签,如果把该标签设置的display属性设置为none,则验证图则会变为下图:

拼接的小方块隐藏掉了,这张图片更容易让我们与原图比对。

然后再找到这个标签,将display设置为block:

原图显示出来,我们可以将上面两张图片的滑动验证图片进行截取,比对,即可找到缺口位置。

实现过程中要注意几点:

1.selenium在加载后,不要立即寻找标签,因为如果标签没有加载完成,会找不到,这样就会抛出错误。

2.截图的大小可以跟浏览器的内显示的大小不一样,需要计算浏览器显示大小与截图大小的比例。

3.进行滑动时,要先加速后减速,如果一直匀速,会被网站识别。

二、实现

1、导入相关要用的包:

from selenium importwebdriverfrom selenium.webdriver.common.by importByfrom selenium.webdriver.support importexpected_conditions as ECfrom selenium.webdriver.support.wait importWebDriverWaitfrom PIL importImagefrom six importBytesIOimporttimefrom selenium.webdriver import ActionChains

2.主函数:

if __name__ == '__main__':

browser=get_url('https://account.zbj.com/login','11111111111','********') #此函数的定义在第3点

time.sleep(1)

slice_img_label= browser.find_element_by_css_selector('div.geetest_slicebg') #找到滑动图片标签

browser.execute_script("document.getElementsByClassName('geetest_canvas_slice')[0].style['display'] = 'none'") #将小块隐藏

full_img_label = browser.find_element_by_css_selector('canvas.geetest_canvas_fullbg') #原始图片的标签

position = get_position(slice_img_label) #获取滑动验证图片的位置,此函数的定义在第4点

screenshot = get_screenshot(browser) #截取整个浏览器图片,此函数的定义在第5点

position_scale = get_position_scale(browser,screenshot) #获取截取图片宽高和浏览器宽高的比例,此函数的定义在第6点

slice_img = get_slideimg_screenshot(screenshot,position,position_scale) #截取有缺口的滑动验证图片,此函数的定义在第7点

browser.execute_script("document.getElementsByClassName('geetest_canvas_fullbg')[0].style['display'] = 'block'") #在浏览器中显示原图

screenshot = get_screenshot(browser) #获取整个浏览器图片

full_img = get_slideimg_screenshot(screenshot,position,position_scale) #截取滑动验证原图browser.execute_script("document.getElementsByClassName('geetest_canvas_slice')[0].style['display'] = 'block'") #将小块重新显示

left = compare(full_img,slice_img) #将原图与有缺口图片进行比对,获得缺口的最左端的位置,此函数定义在第8点

left = left / position_scale[0] #将该位置还原为浏览器中的位置

slide_btn= browser.find_element_by_css_selector('.geetest_slider_button') #获取滑动按钮

track = get_track(left) #获取滑动的轨迹,此函数定义在第9点

move_to_gap(browser,slide_btn,track) #进行滑动,此函数定义在第10点

success = browser.find_element_by_css_selector('.geetest_success_radar_tip') #获取显示结果的标签

time.sleep(2)if success.text == "验证成功":

login_btn= browser.find_element_by_css_selector('button.j-login-btn') #如果验证成功,则点击登录按钮

login_btn.click()else:print(success.text)print('失败')

下面是主函数中用到的各个功能性函数:

3..定义访问页面的函数:

defget_url(url,user,password):

browser=webdriver.Chrome()

browser.get(url)

browser.maximize_window()

wait= WebDriverWait(browser,10)

wait.until(EC.presence_of_element_located((By.CLASS_NAME,'geetest_radar_btn')))

user_input= browser.find_element_by_id('username')

pwd_input= browser.find_element_by_id('password')

btn= browser.find_element_by_css_selector('.geetest_radar_btn')

user_input.send_keys(user)

pwd_input.send_keys(password)

btn.click()

time.sleep(0.5)return browser

此函数主要是用于启动Chrome,打开网页,将用户名和密码填入相应位置,并点击验证按钮。

4.获取滑动验证图片在浏览器的位置。

使用location是获取标签左上角的位置,然后再通过该标签的大小,即可算出其四个角的位置。

defget_position(img_label):

location=img_label.location

size=img_label.size

top, bottom, left, right= location['y'], location['y'] + size['height'], location['x'], location['x'] +size['width']return (left, top, right, bottom)

5.获取整个浏览器的截图。并从内存进行读取。

defget_screenshot(browser):

screenshot=browser.get_screenshot_as_png()

f=BytesIO()

f.write(screenshot)return Image.open(f)

6.通过对比截图和浏览器宽高的大小,算出换算比例。

由于截图是有浏览器的边缘的拖拽条,所以浏览器的宽度+10px

defget_position_scale(browser,screen_shot):

height= browser.execute_script('return document.documentElement.clientHeight')

width= browser.execute_script('return document.documentElement.clientWidth')

x_scale= screen_shot.size[0] / (width+10)

y_scale= screen_shot.size[1] /(height)return (x_scale,y_scale)

7.截取有缺口的滑动图片:

defget_slideimg_screenshot(screenshot,position,scale):

x_scale,y_scale=scale

position= [position[0] * x_scale, position[1] * y_scale, position[2] * x_scale, position[3] *y_scale]return screenshot.crop(position)

8.将原始图片和有缺口的图片进行比较:

defcompare_pixel(img1,img2,x,y):

pixel1=img1.load()[x,y]

pixel2=img2.load()[x,y]

threshold= 50

if abs(pixel1[0]-pixel2[0])<=threshold:if abs(pixel1[1]-pixel2[1])<=threshold:if abs(pixel1[2]-pixel2[2])<=threshold:returnTruereturnFalsedefcompare(full_img,slice_img):

left= 0

for i inrange(full_img.size[0]):for j in range(full_img.size[1]):if notcompare_pixel(full_img,slice_img,i,j):returnireturn left

9.计算出滑动的轨迹,其实就是简单的s = 1/2*a*t*t的简单公式。这部分代码,直接用的崔庆才博主的代码:

defget_track(distance):"""根据偏移量获取移动轨迹

:param distance: 偏移量

:return: 移动轨迹"""

#移动轨迹

track =[]#当前位移

current =0#减速阈值

mid = distance * 4 / 5

#计算间隔

t = 0.2

#初速度

v =0while current

a = 4

else:#加速度为负 3

a = -3

#初速度 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))return track

10.进行移动:

defmove_to_gap(browser,slider, tracks):"""拖动滑块到缺口处

:param slider: 滑块

:param tracks: 轨迹

:return:"""ActionChains(browser).click_and_hold(slider).perform()for x intracks:

ActionChains(browser).move_by_offset(xoffset=x, yoffset=0).perform()

time.sleep(0.5)

ActionChains(browser).release().perform()

以上3-10是定义的功能性函数,放在前面,2是主函数,放在后面。运行即可。也可以将其写为一个类,使用时更为方便。此处,只是为实现功能,所以就没有进一步进行规范。

python爬虫滑动验证码_爬虫:滑动验证解决方法及python实现相关推荐

  1. 爬虫:滑动验证解决方法及python实现

    爬虫时遇到滑动验证,基本思路是通过selenium操作浏览器,将滑动验证的原始图片和缺口图片进行对比,找出缺口位置,然后在利用selenium模拟拖动滑块,达到验证的目的.下面就以猪八戒网为例,进行操 ...

  2. python爬虫绕过验证码_爬虫怎样绕过验证码?

    叶湘伦:[文字篇]如何系统地自学 Python?​zhuanlan.zhihu.com 1,cookie登录利用cookie的特性:cookie会保持较长的时间,来避免用户频繁登录 cookie一般由 ...

  3. java验证码图片滑动验证码_图片滑动验证码的生成

    使用Java生成图片滑动验证码 image.png 目前接到了一个新的小需求,要在登录时进行滑动图片验证. 搜了一下网上的demo,没有太多很完整的demo.就参考各种文档自己拼凑了一个出来.整理一下 ...

  4. 为什么python不能输入中文_一条命令解决mac版本python IDLE不能输入中文问题

    安装完Python通常自动就有了一个简易的集成环境IDLE,但在mac上,无法在IDLE中使用中文. 通常故障有两种情况: 1.在IDLE中,中文输入法根本无法工作,不会弹出输入框,所有的输入都被当做 ...

  5. python图像融合算法_图像融合质量评价方法的python代码实现——MS-SSIM

    图像融合质量评价方法的python代码实现--MS-SSIM 图像融合质量评价方法的python代码实现--MS-SSIM 文章目录 1 前言 2 MS-SSIM介绍 2 MS-SSIM的代码 2.1 ...

  6. Mint-ui中loadmore(上拉加载下拉刷新)组件在ios中滑动会触发点击事件的解决方法...

    bug说明: Mint-ui中loadmore(上拉加载下拉刷新)组件 在 使用fastclick的情况下 ,在ios设备中滑动会触发点击事件: 解决方法: 我是按需引入,去项目中找到loadmore ...

  7. python安装pyecharts清华_基于Python安装pyecharts所遇的问题及解决方法

    最近学习到数据可视化内容,老师推荐安装pyecharts,于是pip install 了一下,结果...掉坑了,下面是我的跳坑经验,如果你有类似问题,希望对你有所帮助. 第一个坑: 这个不难理解,缺少 ...

  8. python 调用event handler_扣丁学堂Python开发之调用语音模块时报错及解决方法

    扣丁学堂Python开发之调用语音模块时报错及解决方法 2018-03-09 11:45:57 3346浏览 python调用语音模块时,遇见TypeError:NoneTypetakesnoargu ...

  9. dedecms织梦系统后台验证码图片不显示的解决方法

    dedecms织梦系统后台验证码图片不显示的解决方法 参考文章: (1)dedecms织梦系统后台验证码图片不显示的解决方法 (2)https://www.cnblogs.com/afish/p/40 ...

最新文章

  1. Eclipse 3.5 Classic+Tomcat 6.0+MySql 5.5搭建java web开发环境
  2. 通用Login功能自动化测试
  3. Html5 小球键盘移动
  4. linux查看系统启动时间
  5. java script应用领域_JavaScript的应用
  6. phpstorm取消自动保存,修改未保存的文件显示*星号
  7. 【转】姚班学霸陈立杰
  8. Win10 Android Fastboot驱动问题
  9. 《数据结构导论自考知识点(自己总结)》
  10. 报错解决:DataLossError: Unable to open table file Data loss: not an sstable (bad magic number):
  11. 路由器与交换机的区别与联系
  12. [渝粤教育] 西南科技大学 外国文学 在线考试复习资料
  13. 爱回收提交订单一直显示服务器来小差,京东的爱回收太垃圾,千万不要用。
  14. 不借助idea开发工具构建一个Javaweb项目
  15. 初期投资60万7-11加盟模式在华将变通
  16. OSChina 周五乱弹 —— 终于发现红薯看片的证据了
  17. csv文件示例_自己动手? -一个简单的CSV解析器示例
  18. 21天减肥法反弹案例-987减肥网
  19. mongdb权限问题
  20. [转载]ZT:趋势交易者的利器----MACD指标在美元指数判断与实战中的运用

热门文章

  1. 手机安卓系统怎么装uvc
  2. 白嫖虚拟主机ZeoCloud亲测免费可用
  3. 服务器上打开excel文件卡顿,win10-打开Excel文件很卡,有什么解决办法?
  4. react在线浏览doc_CodeMirror代码编辑器(react篇)
  5. SQL Server 50道查询训练题,学生Student表
  6. C语言实现PID算法
  7. 怎样给自己的笔记本电脑加装内存条
  8. 关于超宽屏21:9显示器不能调节正确分辨率的解决办法
  9. 手机浏览器被黑_我的手机被黑了,这就是保护自己的方法
  10. CodePNG - 把代码片段变成漂亮截图的免费在线小工具