python爬虫滑动验证码_Python公开课 - 爬虫识别滑动验证码

前言

做爬虫碰到验证码是家常便饭,现在Geetest作为作为一个专业的验证码服务提供商,为不少网站提供了用户行为的验证服务。

其中常见的就是滑动验证,也就是说用户必须手动将滑块拉到对应的图片缺口上。

作为爬虫开发者碰到这类验证码,该如何处理呢,本篇将介绍的一种,通过Selenium模拟用户滑动解锁方法。

我们以得意网登录页面为例阐述

分析网页信息

得意网的极验证是登录弹框的方式出现的,当输入用户名和密码后,点击登录将弹出极验证

弹出极验证后,我们对图片元素进行分析,发现下载了三张图片,两个.webp图像文件为一个完整图和一个有缺口的图,而.png图像文件则是滑块,但是不管是完整图合适含缺口的图,都是乱序的。那么接下来,我们需要将图片还原成正常显示的。

还原并合成图片

分析图片元素的样式信息,我们可以看到图片是合成的,也就是说你只保存所有地址的图片是不行的。它是通过background-position的方法进行合成的。

获取原始图片的及位置信息:

def get_image_and_location():

options = Options()

options.binary_location = '/usr/bin/google-chrome'

options.add_argument('--headless')

options.add_argument('--disable-gpu')

options.add_argument('--no-sandbox')

driver = webdriver.Chrome(executable_path='./chromedriver', chrome_options=options)

driver.implicitly_wait(5)

driver.get("http://www.deyi.com/account.php?mod=login")

content = driver.find_elements_by_class_name('gt_cut_bg_slice')

cut_loc_list = []

img_url = None

for i in content:

style = i.get_attribute("style")

import re

img_url, x, y = re.findall('url\(\"(.*)\"\); background-position: (.*)px (.*)px;', style)[0]

cut_loc_list.append({'x':int(x), 'y': int(y)})

import requests

r = requests.get(img_url)

with open('cut.webp', 'wb') as f:

f.write(r.content)

from PIL import Image

im = Image.open("cut.webp")

rgb_im = im.convert('RGB')

rgb_im.save('cut.jpg')

content = driver.find_elements_by_class_name('gt_cut_fullbg_slice')

full_loc_list = []

img_url = None

for i in content:

style = i.get_attribute("style")

import re

img_url, x, y = re.findall('url\(\"(.*)\"\); background-position: (.*)px (.*)px;', style)[0]

full_loc_list.append({'x':int(x), 'y': int(y)})

import requests

r = requests.get(img_url)

with open('full.webp', 'wb') as f:

f.write(r.content)

from PIL import Image

im = Image.open("full.webp")

rgb_im = im.convert('RGB')

rgb_im.save('full.jpg')

driver.quit()

return ('cut.jpg', cut_loc_list, 'full.jpg', full_loc_list)

还原合成图片的代码如下:

def get_merge_image(filename, location_list):

from PIL import Image as image

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)))

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

经过处理后,可以正常还原出来两张图片full.jpg, cut.jpg

计算缺口位置

在得到了两张图片后,我们需要对他们进行比较,来计算缺口的位置,以便于移动滑块到指定的位置

思路简单点来说,就是设定一个阈值,对每个像素进行比较,找到像素不同的那个点

考虑到滑块的像素为60,所以我们可以设置起始位置为60

方法代码如下:

def get_distance(image1,image2):

left=60

threhold=70

for i in range(left,image1.size[0]):

for j in range(image1.size[1]):

rgb1=image1.load()[i,j]

rgb2=image2.load()[i,j]

res1=abs(rgb1[0]-rgb2[0])

res2=abs(rgb1[1]-rgb2[1])

res3=abs(rgb1[2]-rgb2[2])

if not (res1 < threhold and res2 < threhold and res3 < threhold):

return i

return left

划重点- 核心逻辑之移动滑块算法

在获得缺口位置后,只需要移动滑块即可,但是这里极验证对轨迹数据也进行了校验,换句话说,如果轨迹模拟被识别出是程序控制的,极验证也无法通过,这种情况会出提示信息“怪兽吃了拼图 再来一次”

经过尝试,这里给出一个简单可靠的算法

slider=driver.find_element_by_class_name("gt_slider_knob")

from selenium.webdriver import ActionChains

ActionChains(driver).click_and_hold(slider).perform()

left = dis-6

while left>0:

import random

x = min(random.randint(20, 30), left)

print x

ActionChains(driver).move_by_offset(xoffset=x, yoffset=-1).perform()

left -= x

time.sleep(random.random() + 0.15)

ActionChains(driver).release().perform()

至此大功搞成,可以正常实现自动登录或者注册了。

总结

极验证的滑动验证具体还是需要先了解一下页面情况,具体情况具体分析。其中的难点还是滑块的拖动轨迹处理,处理不好,一切白费。

相关阅读

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值