一、登录网址跳转到滑块验证码界面
登录网址:
url=https://account.zbj.com/login
先拿到这个标签,在跳转到滑块验证码界面。
from selenium import webdriver
driver=webdriver.Chrome()
driver.implicitly_wait(10)
#登录网址
driver.get('https://account.zbj.com/login')
driver.maximize_window()
#点击验证
driver.find_element_by_xpath('//*[@id="utopia_widget_10"]/ul/ol/a/span/img').click()
driver.find_element_by_class_name("geetest_radar_tip").click()
跳转出的结果图:
?二、验证码图片的处理
验证码图片有缺口图、滑块图、完整图,三张构成。
逻辑思想:1.让滑块隐藏,截取缺口图;
??????????????????2.隐藏缺口图,显示滑块图,截取滑块图;
? ? ? ? ? ? ? ? ? 3.显示完整图,截取完整图。
import time
from selenium import webdriver
def get_captcha():
'''取得验证码的图片'''
time.sleep(2)
#1、隐藏滑块,得到缺口图
js_hide_slice = 'document.getElementsByClassName("geetest_canvas_slice")[0].style.display="none"'
driver.execute_script(js_hide_slice)
#截取缺口图
part_imgpath='./part.png'
driver.find_element_by_class_name("geetest_canvas_bg").screenshot(part_imgpath)
#2、隐藏缺口图 ,得到滑块图
js_show_slice='document.getElementsByClassName("geetest_canvas_slice")[0].style.display="block"'
js_hide_part='document.getElementsByClassName("geetest_canvas_bg")[0].style.display="none"'
driver.execute_script(js_show_slice+";"+js_hide_part)
#截取滑块图
slice_imgpath='./slice.png'
driver.find_element_by_class_name("geetest_canvas_slice").screenshot(slice_imgpath)
#3、显示完整图 geetest_canvas_fullbg
js_show_full1='document.getElementsByClassName("geetest_canvas_fullbg")[0].style.opacity="1"'
js_show_full2='document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display="block"'
driver.execute_script(js_show_full1+";"+js_show_full2)
#截取完整图形
full_imgpath='./full.png'
driver.find_element_by_class_name("geetest_canvas_fullbg").screenshot(full_imgpath)
#还原
js_hide_full1='document.getElementsByClassName("geetest_canvas_fullbg")[0].style.opacity="0"'
js_hide_full2='document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display="none"'
js_show_part='document.getElementsByClassName("geetest_canvas_bg")[0].style.display=""'
driver.execute_script(js_hide_full1+";"+js_hide_full2+";"+js_show_part)
return part_imgpath,slice_imgpath,full_imgpath
if __name__ == '__main__':
driver=webdriver.Chrome()
driver.implicitly_wait(10)
#登录网址
driver.get('https://account.zbj.com/login')
driver.maximize_window()
#点击验证
driver.find_element_by_xpath('//*[@id="utopia_widget_10"]/ul/ol/a/span/img').click()
driver.find_element_by_class_name("geetest_radar_tip").click()
time.sleep(1)
# 获取缺口图,滑块图,完整图
part_imgpath, slice_imgpath, full_imgpath = get_captcha()
取到了三张图片:
三、计算距离
逻辑思想:
#逻辑思路
def get_slice_X():
'''获取滑块左边缘X'''
pass
def get_gap_X():
'''获取缺口左边缘x坐标'''
pass
def get_distance():
'''计算距离'''
pass
接下来对获取的滑块左边缘X进行编写与测试取值:建一个py文件,将下面代码放入,运行。
from PIL import Image
part_imgpath='./part.png'
slice_imgpath='./slice.png'
full_imgpath = './full.png'
def get_slice_X(slice_imgpath):
'''获取滑块左边缘X'''
img=Image.open(slice_imgpath)
w,h=img.size
for i in range(w):
for j in range(h):
rgb=img.getpixel((i,j))
print((i,j),rgb)
if rgb[0]+rgb[1]+rgb[2]<250:
return (i,j),rgb
data=get_slice_X(slice_imgpath)
print(data)
运行结果:?
?对获取缺口左边缘X坐标进行编写和测试:建立.py文件放入代码
from PIL import Image
part_imgpath='./part.png'
slice_imgpath='./slice.png'
full_imgpath = './full.png'
def get_gap_X(part_imgpath,full_imgpath):
'''获取缺口左边缘x坐标'''
part_img = Image.open(part_imgpath)
full_img = Image.open(full_imgpath)
w, h = part_img.size
for i in range(w):
for j in range(h):
part_point = part_img.getpixel((i, j))
full_point = full_img.getpixel((i, j))
#比较缺口图与完整图,相同坐标点,颜色差,缺口位置色差比较大
r = part_point[0] - full_point[0]
g = part_point[1] - full_point[1]
b = part_point[2] - full_point[2]
abs_value = abs(r) + abs(g) + abs(b)
if abs_value>120:
return i,j
print("abs_value",(r,g,b),abs_value,(i,j))
data=get_gap_X(part_imgpath,full_imgpath)
print(data)
运行结果:?
?计算距离:
def get_distance(slice_imgpath,part_imgpath,full_imgpath):
slice_X = get_slice_X(slice_imgpath)[0][0]
gap_X = get_gap_X(full_imgpath, part_imgpath)[0]
distance = gap_X - slice_X
return distance
四、模拟人工运动
1、直接根据获取到的距离移动,滑块与缺口能够契合但是不能通过
2、牛顿运动定律模拟人工移动,偶尔有通过,概率低。
3、增加随机性模拟人工移动轨迹,通过概率高。
五、移动滑块
def move_slider(tracks):
element=driver.find_element_by_class_name("geetest_slider_button")
ActionChains(driver).click_and_hold(element).perform()
for x in tracks:
ActionChains(driver).move_by_offset(xoffset=x,yoffset=0).perform()
ActionChains(driver).release(element).perform()
time.sleep(2)
完整代码:
import time
from PIL import Image
from selenium import webdriver
import random
from selenium.webdriver.common.by import By
from shu import * #我自己导的要输入的账号密码包
from selenium.webdriver import ActionChains
#一、获取图片
def get_captcha():
'''取得验证码的图片'''
time.sleep(2)
#1、隐藏滑块,得到缺口图
js_hide_slice = 'document.getElementsByClassName("geetest_canvas_slice")[0].style.display="none"'
driver.execute_script(js_hide_slice)
#截取缺口图
part_imgpath='./part.png'
driver.find_element_by_class_name("geetest_canvas_bg").screenshot(part_imgpath)
#2、隐藏缺口图 ,得到滑块图
js_show_slice='document.getElementsByClassName("geetest_canvas_slice")[0].style.display="block"'
js_hide_part='document.getElementsByClassName("geetest_canvas_bg")[0].style.display="none"'
driver.execute_script(js_show_slice+";"+js_hide_part)
#截取滑块图
slice_imgpath='./slice.png'
driver.find_element_by_class_name("geetest_canvas_slice").screenshot(slice_imgpath)
#3、显示完整图 geetest_canvas_fullbg
js_show_full1='document.getElementsByClassName("geetest_canvas_fullbg")[0].style.opacity="1"'
js_show_full2='document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display="block"'
driver.execute_script(js_show_full1+";"+js_show_full2)
#截取完整图形
full_imgpath='./full.png'
driver.find_element_by_class_name("geetest_canvas_fullbg").screenshot(full_imgpath)
#还原
js_hide_full1 = 'document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display="none"'
js_hide_full2 = 'document.getElementsByClassName("geetest_canvas_fullbg")[0].style.opacity="0"'
js_show_part='document.getElementsByClassName("geetest_canvas_bg")[0].style.display=""'
driver.execute_script(js_hide_full1+";"+js_hide_full2+";"+js_show_part)
return slice_imgpath,part_imgpath,full_imgpath
#二、计算距离
def get_slice_X(slice_imgpath):
'''获取滑块左边缘X'''
img = Image.open(slice_imgpath)
w, h = img.size
for i in range(w):
for j in range(h):
rgb = img.getpixel((i, j))
print((i, j), rgb)
if rgb[0] + rgb[1] + rgb[2] < 250:
return (i, j), rgb
def get_gap_X(part_imgpath,full_imgpath):
'''获取缺口左边缘x坐标'''
part_img = Image.open(part_imgpath)
full_img = Image.open(full_imgpath)
w, h = part_img.size
for i in range(w):
for j in range(h):
part_point = part_img.getpixel((i, j))
full_point = full_img.getpixel((i, j))
#比较缺口图与完整图,相同坐标点,颜色差,缺口位置色差比较大
r = part_point[0] - full_point[0]
g = part_point[1] - full_point[1]
b = part_point[2] - full_point[2]
abs_value = abs(r) + abs(g) + abs(b)
if abs_value>110:
return i,j
def get_distance(slice_imgpath,part_imgpath,full_imgpath):
slice_X = get_slice_X(slice_imgpath)[0][0]
gap_X = get_gap_X(full_imgpath, part_imgpath)[0]
distance = gap_X - slice_X
return distance
#三、模拟人工移动
def get_track(distance):
#初速度
v=0
#单位时间为0.2s来统计轨迹,轨迹即0.2内的位移
t=0.2
# 位移/轨迹列表、列表内的一个元素代表0.2s的位移
tracks = []
#当前的位移
current=0
#到达mid值开始减速
mid=distance*5/8
distance+=10 #先滑过一点,最后再反着滑动回来
while current<distance:
t=random.randint(1,4)/10 #将时间设为随机,更符合人的行为
if current<mid:
#加速度越小,单位时间的位移越小,模拟的轨迹就越多越详细
a=random.randint(1,3)#加速运动
else:
a=random.randint(2,4)#减速运动
#初速度
v0=v
#t秒时间内的位移
s=v0*t+0.5*a*(t**2)
#当前的位置
current+=s
#添加到轨迹列表
tracks.append(round(s))
#速度已经达到v,该速度作为下次的初速度
v=v0+a*t
#反着滑动到大概准确位置
temp=10+round(current-distance)#比原来正确的位置多了的像素
for i in range(5):
num=-random.randint(1,3)
tracks.append(num)
temp+=num
#位移的补偿
tracks.append(abs(temp))if temp<0 else tracks.append(-temp)
# random.shuffle(tracks)
print(tracks)
return tracks
# selenium操作
#移动滑块
def move_slider(tracks):
element=driver.find_element_by_class_name("geetest_slider_button")
ActionChains(driver).click_and_hold(element).perform()
for x in tracks:
ActionChains(driver).move_by_offset(xoffset=x,yoffset=0).perform()
ActionChains(driver).release(element).perform()
time.sleep(2)
if __name__ == '__main__':
driver=webdriver.Chrome()
driver.implicitly_wait(10)
#登录网址
driver.get('https://account.zbj.com/login')
driver.maximize_window()
#点击验证
driver.find_element_by_xpath('//*[@id="utopia_widget_10"]/ul/ol/a/span/img').click()
driver.find_element_by_class_name("geetest_radar_tip_content").click()
time.sleep(1)
#账号和密码
name = driver.find_element(By.NAME, 'username').send_keys(USER)
password = driver.find_element(By.NAME, 'password').send_keys(PASSWORD)
time.sleep(2)
# 获取缺口图,滑块图,完整图
part_imgpath, slice_imgpath, full_imgpath = get_captcha()
# 获取距离
distance = get_distance(part_imgpath, slice_imgpath, full_imgpath)
print(distance)
count=6
while count>0:
# 获取轨迹
tracks = get_track(distance)
# selenium操作
move_slider(tracks)
success=driver.find_element_by_class_name("geetest_success_radar_tip_content").text
if success:
print("校验成功",success)
time.sleep(1)
driver.find_element_by_class_name("zbj-btn-primary").click()
break
else:
count+=1
#出现被怪兽吃掉,网络不给力
info_tag=driver.find_element_by_class_name("geetest_reset_tip_content")
internet_info=info_tag.text
if "点击重试" in internet_info:
info_tag.click()
# 获取缺口图,滑块图,完整图
part_imgpath, slice_imgpath, full_imgpath = get_captcha()
# 获取距离
distance = get_distance(part_imgpath, slice_imgpath, full_imgpath)
print(distance)
# element = driver.find_element_by_class_name("geetest_slider_button")
# ActionChains(driver).click_and_hold(element).perform()
# ActionChains(driver).move_by_offset(xoffset=distance, yoffset=0).perform()
# ActionChains(driver).release(element).perform()
time.sleep(10)
# driver.close()
账号与密码的py文件
USER='xxxxx' #你自己注册的账号
PASSWORD='xxxxx' #密码
最后要说的是,在 49行的取的250这个值是个大概范围值,可能要多运行几次才能成功,但逻辑,代码还行吧。
def get_slice_X(slice_imgpath):
'''获取滑块左边缘X'''
好多步骤都省了,是直接上的代码,就参考学习吧。哈哈!
?
|