Python实现滑块验证 | 世外天堂

Python实现滑块验证

python中安装好selenium包 pip install selenium
点击下载chrome的webdriver: http://chromedriver.storage.googleapis.com/index.html,目前只有32位的。
1.驱动下载完成,解压
2.将解压后文件chromedriver.exe复制到python的Scripts安装目录下(我的:E:\Python\Python36-32\Scripts),并且添加到path环境变量
3.将目录chrome的安装目录添加到path环境变量。(我的:C:\Program Files (x86)\Google\Chrome\Application\chrome.exe)
4.运行下面代码:成功打开百度即为成功:(别拉到cmd里直接运行,各种报错,我是在VS终端下调试成功的)
from selenium import webdriver
driver = webdriver.Chrome()
  driver.get(‘http://www.baidu.com')

然后是详细代码:(代码转自奥哥)

seleclass.py主入口文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# -*- coding: utf-8 -*-
import json
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from image_diff import Diff


class SeleClass:
def __init__(self, url, username, password):
self.url = url
self.wdc_option = webdriver.ChromeOptions()
self.wdc_option.add_argument('--headless')
self.wdc_option.add_argument('--disable-gpu')
self.wdc = webdriver.Chrome(options=self.wdc_option)
self.wdc.implicitly_wait(10)
self.wdc.get(self.url)
self.wdc.maximize_window()
self.input(username, password)

def input(self, username, password):
self.wdc.find_element_by_id('login-username').send_keys(username)
self.wdc.find_element_by_id('login-passwd').send_keys(password)
self.mouseLogin()

def mouseLogin(self):
ActionChains(self.wdc).move_to_element(self.wdc.find_elements_by_class_name('btn-login')[0]).perform()
ActionChains(self.wdc).click().perform()
self.mouseMove(Diff(**self.getBase64Data()).hOption())
self.isLogin()

def doScript(self, script):
for _ in range(10):
try:
if len(self.wdc.execute_script(script)) < 3000:
print('错误数据大小:%s' % len(self.wdc.execute_script(script)), end='\t')
raise BaseException()
return self.wdc.execute_script(script)
except:
time.sleep(1)
raise BaseException('拉取数据超时')

def mouseMove(self, long):
print('鼠标移动位移为:%s' % long)
ActionChains(self.wdc).click_and_hold(
self.wdc.find_elements_by_class_name('geetest_slider_button')[0]).perform()
ActionChains(self.wdc).move_by_offset(long, 0).perform()
time.sleep(1)
ActionChains(self.wdc).release().perform()

def getBase64Data(self):
bg = self.doScript("return $('.geetest_canvas_bg')[0].toDataURL('image/png')")[22::]
full = self.doScript("return $('.geetest_canvas_fullbg')[0].toDataURL('image/png')")[22::]
slice = self.doScript("return $('.geetest_canvas_slice')[0].toDataURL('image/png')")[22::]
print('真实数据大小:', len(bg), len(full), len(slice))
return {
'b1': bg,
'b2': full,
'b3': slice
}

def isLogin(self):
for _ in range(10):
if self.wdc.get_cookie('DedeUserID'):
self.wdc.get('https://space.bilibili.com/' + self.wdc.get_cookie('DedeUserID')['value'])
print('登陆成功:%s' % self.wdc.find_element_by_id('h-name').text)
return
else:
time.sleep(1)
raise BaseException('页面跳转超时')

def __del__(self):
time.sleep(2)
self.wdc.close()


if __name__ == '__main__':
s = SeleClass('https://passport.bilibili.com/login', 'username', 'password')

image_diff.py图片处理文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from skimage.measure import compare_ssim
import argparse
import imutils
import cv2
import numpy as np
from base64 import b64decode


class Diff:
def __init__(self, b1, b2, b3):
self.imageA = cv2.imdecode(np.frombuffer(b64decode(b1), np.uint8), cv2.COLOR_RGB2BGR)
self.imageB = cv2.imdecode(np.frombuffer(b64decode(b2), np.uint8), cv2.COLOR_RGB2BGR)
self.imageC = cv2.imdecode(np.frombuffer(b64decode(b3), np.uint8), cv2.COLOR_RGB2BGR)

def show(self):
cv2.imshow('imga', self.imageA)
cv2.imshow('imgb', self.imageB)
cv2.imshow('imgc', self.imageC)
if chr(cv2.waitKey(0)) == 'q':
cv2.destroyAllWindows()

def hOption(self):
grayA = cv2.cvtColor(self.imageA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(self.imageB, cv2.COLOR_BGR2GRAY)
grayC = cv2.cvtColor(self.imageC, cv2.COLOR_BGR2GRAY)
npArr_3 = np.array(grayC)
return self.diff(grayA, grayB, npArr_3)

def diff(self, grayA, grayB, npArr_3):
(score, diff) = compare_ssim(grayA, grayB, full=True)
diff = (diff * 255).astype("uint8")
print('图片相似度为:%s' % score)
return self.tf(diff, npArr_3)

def tf(self, diff, npArr_3):
thresh = cv2.threshold(diff, 0, 255,
cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[1] if imutils.is_cv3() else cnts[0]

img3_t = cv2.threshold(npArr_3, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

cnts_3 = cv2.findContours(img3_t.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts_3 = cnts_3[1] if imutils.is_cv3() else cnts_3[0]
return self.getBr(cnts, cnts_3)

def getBr(self, cnts, cnts_3):
x1, y1, w1, h1 = cv2.boundingRect(cnts[-1])
cv2.rectangle(self.imageA, (x1, y1), (x1 + w1, y1 + h1), (0, 0, 255), 1)
cv2.rectangle(self.imageB, (x1, y1), (x1 + w1, y1 + h1), (0, 0, 255), 1)
x2, y2, w2, h2 = cv2.boundingRect(cnts_3[-1])
cv2.rectangle(self.imageC, (x2, y2), (x2 + w2, y2 + h2), (0, 0, 255), 1)
cv2.rectangle(self.imageC, (x2, y2), (x2 + w2, y2 + h2), (0, 0, 255), 1)
return x1 - x2