@[toc]
图片比对
昨天的博客已经将图片存储到了本地,今天要做的第一件事情,就是需要在两张图片中进行比对,将图片缺口定位出来
缺口图片
完整图片
计算缺口坐标
对比两张图片的所有RBG像素点,得到不一样像素点的x值,即要移动的距离
def get_distance(self,cut_image,full_image):
# print(cut_image.size)
threshold = 50
for i in range(0,cut_image.size[0]):
for j in range(0,cut_image.size[1]):
pixel1 = cut_image.getpixel((i, j))
pixel2 = full_image.getpixel((i, j))
res_R = abs(pixel1[0] - pixel2[0]) # 计算RGB差
res_G = abs(pixel1[1] - pixel2[1]) # 计算RGB差
res_B = abs(pixel1[2] - pixel2[2]) # 计算RGB差
if res_R > threshold and res_G > threshold and res_B > threshold:
return i # 需要移动的距离
极验证对于用户行为检测是有专门的算法的,找到一篇比较老的文章
如果我们直接把上面算出来的缺口位置放到前面脚本里,你会发现即使移动的位置正确了,提示却是“怪物吃了饼图”,验证不通过。很显然,geetest识别出了这个动作并不是人的行为。这我们就需要去查看自然人滑动鼠标和我们代码实现的滑动在轨迹上有什么不同。
鼠标拖动滑块进行移动的时候,也是遵循人类行为的,这个地方,你可以参考文章
移动滑块
这部分和我们之前滑动验证码识别是一致的,通过selenium进行人行为实现
# 移动滑块
def start_move(self, distance):
element = self.driver.find_element_by_xpath('//div[@class="gt_slider_knob gt_show"]')
# 使用滑块的一半进行偏移设置
distance -= element.size.get('width') / 2
distance += 15
# 按下鼠标左键
ActionChains(self.driver).click_and_hold(element).perform()
time.sleep(0.5)
while distance > 0:
if distance > 20:
# 如果距离大于20,就让他移动快一点
span = random.randint(5, 8)
else:
# 快到缺口了,就移动慢一点
span = random.randint(2, 3)
ActionChains(self.driver).move_by_offset(span, 0).perform()
distance -= span
time.sleep(random.randint(10, 50) / 100)
ActionChains(self.driver).move_by_offset(distance, 1).perform()
ActionChains(self.driver).release(on_element=element).perform()
运行效果,第一次验证失败了,等待7秒左右进行第二次验证,注意成功了。
最后要调整的是验证失败,需要重复验证
验证失败
验证失败,在拖动的下面继续编写即可,属于正常的逻辑代码了
self.start_move(dis)
# 如果出现错误
try:
WebDriverWait(self.driver, 5).until(
EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_ajax_tip gt_error"]')))
print("验证失败")
return
except TimeoutException as e:
pass
# 判断是否验证成功
try:
WebDriverWait(self.driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_ajax_tip gt_success"]')))
except TimeoutException:
print("重新验证....")
time.sleep(5)
# 失败后递归执行拖动
self.analog_drag()
else:
print("验证成功")
写在后面
到此为止,极验证已经编写完毕,代码中还有很多地方需要进行调整
例如
element = self.driver.find_element_by_xpath('//div[@class="gt_slider_knob gt_show"]')
上面获取元素的方式,很容易导致目标元素没有捕获到,然后项目直接报错退出,所以需要进行完善
driver 需要及时的关闭,否则会在你的任务管理器中出现大量的chromedriver.exe
进程
极验证验证码破解方式基本遵循滑动验证码,核心内容在于两个图片的处理,希望你可以学习到。
扫码关注微信公众账号,回复0321获取验证码源码