python 滑块验证码 没有原图 自动完成验证

2021/5/13 14:57:12

本文主要是介绍python 滑块验证码 没有原图 自动完成验证,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

遇到过淘宝的滑块验证(只有一个从头到底的滑动),还有类似京东的登录滑块(有缺口的)

1、淘宝的滑块比较简单,直接用selenium的ActionChain(但后来发现淘宝做了模拟浏览器的检测机制,解决要点在怎么扰乱他的检查,这个可以看另一篇文章解决:TODO)

类似这种

 

 

  

2、类似京东的这种缺口验证码,有两种,一种是前端有暴露原图,另一种是没有暴露原图。暴露原图的要简单一些,没有暴露原图的要引入cv2库来解决

第一种:

(图一)完整初始图

 

(图二)缺失的块图

 

 

  

(图三)滑块

 

 

(图四)原图(没有暴露下面这张原图的,要稍微麻烦点)

 

 

注意:稍微好点儿的站点都做了滑动时的速度检测机制,会被判定为机器人行为(如京东)。淘宝做的是直接检测是否是模拟浏览器(你完成拖动后,会报:
哎呀,出错了,点击刷新再来一次(error:9AA9Jd)

 

 

 

 

这里只贴了没有原图的自动验证代码: 

  1 #!/usr/bin/python
  2 # -*- coding:utf-8 -*-
  3 
  4 import requests
  5 import cv2
  6 from PIL import Image
  7 from selenium import webdriver
  8 import pyautogui
  9 from numpy import random
 10 import time
 11 
 12 
 13 class SliderVerificationCode:
 14 
 15     def __init__(self):
 16         url = 'https://console.ecapi.cn/user/login'
 17         self.driver = self.get_url(url, '11111', '222222')
 18 
 19     def get_url(self, url, user, password):
 20         browser = webdriver.Chrome(executable_path=r'E:\python\GeckoDriver\chromedriver.exe')
 21         browser.get(url)
 22         browser.maximize_window()
 23         time.sleep(3)
 24         user_input = browser.find_element_by_xpath('//*[@id="username"]')
 25         pwd_input = browser.find_element_by_xpath('//*[@id="password"]')
 26         btn = browser.find_element_by_xpath('//*[@id="formLogin"]/div[4]/div/div/span/button')
 27         user_input.send_keys(user)
 28         pwd_input.send_keys(password)
 29         btn.click()
 30         time.sleep(0.5)
 31         return browser
 32 
 33     def get_image(self):
 34         time.sleep(3)
 35         print('frame location:', self.driver.find_element_by_id('tcaptcha_iframe').location)
 36         self.driver.switch_to.frame('tcaptcha_iframe')
 37         self.target = self.driver.find_element_by_xpath('//*[@id="slideBg"]')
 38         self.template = self.driver.find_element_by_xpath('//*[@id="slideBlock"]')
 39         self.download_img(self.target.get_attribute('src'), 'target.png')
 40         self.download_img(self.template.get_attribute('src'), 'temlate.png')
 41 
 42         # 下载下来的原图网页的css有调整尺寸,这样就需要按照网页的尺寸来计算偏移
 43         self.resize_image('target.png', 'target.png', 341, 195, 'png')
 44         self.resize_image('temlate.png', 'temlate.png', 68, 68, 'png')
 45 
 46     def resize_image(self, filein, fileout, width, height, type):
 47         img = Image.open(filein)
 48         out = img.resize((width, height), Image.ANTIALIAS)
 49         # resize image with high-quality
 50         out.save(fileout, type)
 51 
 52     def download_img(self, img_url, save_name):
 53         host_referer = {
 54             'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
 55         }
 56         print('download:' + img_url)
 57         html = requests.get(img_url, headers=host_referer)
 58         # 图片不是文本文件,以二进制格式写入,所以是html.content
 59         f = open(save_name, 'wb')
 60         f.write(html.content)
 61         f.close()
 62 
 63     def find_pic(self, target='target.png', template='temlate.png'):
 64         target_rgb = cv2.imread(target)
 65         target_gray = cv2.cvtColor(target_rgb, cv2.COLOR_RGB2GRAY)
 66         template_rgb = cv2.imread(template, 0)
 67         res = cv2.matchTemplate(target_gray, template_rgb, cv2.TM_CCOEFF_NORMED)
 68         value = cv2.minMaxLoc(res)
 69         # print(value)
 70         return value[2][0]
 71 
 72     def size(self):
 73         x = self.find_pic()
 74         img = cv2.imread('target.png')
 75         w1 = img.shape[1]
 76         w2 = self.target.size['width']
 77         self.offset = int(x * w2 / w1 + 25)  # 这个25没搞清楚为什么是25...
 78         print(self.offset)
 79 
 80     def drag(self):
 81         time.sleep(3)
 82         The_slider = self.driver.find_element_by_xpath('//*[@id="tcaptcha_drag_button"]')
 83         # 780:是验证码弹窗距离浏览器最左边的x轴距离(因为在整个验证码弹窗是个iframe,所以这个元素的x定位是以iframe的来计算的)
 84         # 284:是y轴的
 85         x = The_slider.location.get('x') + 780  # 滑块的初始x位置
 86         y = The_slider.location.get('y') + 284
 87         print(The_slider.location, ',kw_x = ', x, ',kw_y = ', y)
 88         xx = self.offset + 780 - 11  # offset=缺口到iframe边框的距离
 89 
 90         pyautogui.moveTo(x, y + 127, duration=0.1)
 91 
 92         pyautogui.mouseDown()
 93 
 94         y += random.randint(9, 19)
 95         pyautogui.moveTo(x + int(self.offset * random.randint(15, 23) / 20), y, duration=0.28)
 96 
 97         y += random.randint(-9, 0)
 98         pyautogui.moveTo(x + int(self.offset * random.randint(17, 21) / 20), y, duration=(random.randint(20, 31)) / 100)
 99 
100         y += random.randint(0, 8)
101         pyautogui.moveTo(xx, y, duration=0.3)
102 
103         # self.driver.save_screenshot('fullscreen.png')
104         print('finally x:{},y:{}'.format(xx, y))
105 
106         pyautogui.mouseUp()
107 
108 
109 if __name__ == '__main__':
110     p = SliderVerificationCode()
111     p.get_image()
112     p.find_pic()
113     p.size()
114     p.drag()
115     print('end')

 

 

PPS:用到的额外的插件包括:cv2(仓库名是opencv-python)、numpy

pip install时,如果非常慢,可以通过镜像来安装:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy

安装完后,代码里面有警告,提示找不到引用,这里搞了半天没解决,但代码能正确执行,暂时就没解决了,有解决掉的,烦请告知!

 

 

本文源码大部分摘自:https://blog.csdn.net/qq_42899854/article/details/110671815(python实现滑动京东滑块验证码)



这篇关于python 滑块验证码 没有原图 自动完成验证的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程