那么就直接上代码
import time
from PIL import Image
import random
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# from py import password
from shu import * #导入自己的账号密码包
# 三个canvas标签分别对应了缺口图,滑块图和完整图
def canvas():
time.sleep(3)
# 1.让滑块隐藏,截取缺口图;
slice_js = 'document.getElementsByClassName("geetest_canvas_slice")[0].style.display="none"'
driver.execute_script(slice_js)
slice_path = r'./slice.png'
driver.find_element(By.CLASS_NAME,"geetest_canvas_bg").screenshot(slice_path)
# # 2.隐藏缺口图,显示滑块图,截取滑块图;
slice_js1 = 'document.getElementsByClassName("geetest_canvas_slice")[0].style.display=""'
bg_js='document.getElementsByClassName("geetest_canvas_bg")[0].style.display="none"'
driver.execute_script(bg_js+';'+slice_js1)
bg_path=r'./bg.png'
driver.find_element(By.CLASS_NAME,'geetest_canvas_slice').screenshot(bg_path)
# #3.截取完整图
fullbg_js = 'document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display="block"'
driver.execute_script(fullbg_js)
fullbg_path=r'./fullbg.png'
driver.find_element(By.CLASS_NAME,'geetest_canvas_fullbg').screenshot(fullbg_path)
# 4.显示完整图
bg_js1 = 'document.getElementsByClassName("geetest_canvas_bg")[0].style.display=""'
fullbg_js1 = 'document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display=""'
driver.execute_script(bg_js1+';'+fullbg_js1)
return bg_path,slice_path,fullbg_path
# 计算距离
def get_x(bg_path):
#计算滑块图左边缘的距离
bgimg=Image.open(bg_path)
x,y=bgimg.size
for i in range(x):
for j in range(y):
# 彩色图片每个点是一个元祖,
bg=bgimg.getpixel((i,j))
#将彩色图片的像素点相加,返回一个小于250的坐标
if bg[0]+bg[1]+bg[2] <250:
return (i,j),bg
def get_X(slice_path,fullbg_path):
#获取缺口左边缘的X坐标
slimg=Image.open(slice_path)
fulimg=Image.open(fullbg_path)
x,y=slimg.size
for w in range(x):
for h in range(y):
# 彩色图片每个点是一个元祖
sl_img=slimg.getpixel((w,h))
ful_img=fulimg.getpixel((w,h))
#将完整图和滑块图作比较
r=ful_img[0]-sl_img[0]
g=ful_img[1]-sl_img[1]
b=ful_img[2]-sl_img[2]
abs_value=abs(r)+abs(g)+abs(b)
if abs_value >120:
return w,h
# 计算距离, 距离=滑块左边缘的X坐标-滑块右边缘的X坐标
def get_distance(bg_path,slice_path,fullbg_path):
# 缺口图的距离
get_X1=get_X(slice_path, fullbg_path)[0]
# 计算距离
# 滑块图的距离
get_x1=get_x(bg_path)[0][0]
dis=get_X1-get_x1
return dis
#三.模拟人工移动
def get_track(distance):
'''
拿到移动轨迹,模仿人的滑动行为,先匀加速后匀减速
匀变速运动基本公式:
①v=v0+at
②s=v0t+(1/2)at²
③v²-v0²=2as
:param distance: 需要移动的距离
:return: 存放每0.2秒移动的距离
'''
# 初速度
v = 0
# 单位时间为0.2s来统计轨迹,轨迹即0.2内的位移
t = 0.2
# 位移/轨迹列表,列表内的一个元素代表0.2s的位移
tracks = []
# 当前的位移
current = 0
# 到达mid值开始减速
mid = distance * 5 / 8
distance += 10 # 先滑过一点,最后再反着滑动回来
# a = random.randint(1,3)
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
# 0.2秒时间内的位移
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
#seleium操作
def move(tracks):
button=driver.find_element(By.CLASS_NAME,'geetest_slider_button')
#显示等待
# WebDriverWait(driver,timeout=10).until(EC.element_to_be_selected(button))
ActionChains(driver).click_and_hold(button).perform()
for x in tracks:
ActionChains(driver).move_by_offset(xoffset=x,yoffset=0).perform()
ActionChains(driver).release(button).perform()
time.sleep(2)
driver=webdriver.Chrome()
driver.implicitly_wait(10)
driver.get('https://account.zbj.com/login?isFromIndex=1&fromurl=https%3A%2F%2Fweinan.zbj.com%2F')
# 窗口最大化
driver.maximize_window()
#点击
time.sleep(2)
driver.find_element(By.CSS_SELECTOR,'#utopia_widget_10 > ul > ol > a > span >img').click()
#输入账号
driver.find_element(By.ID,'username').send_keys(USER)
#输入密码
driver.find_element(By.ID,'password').send_keys(PASSWORD)
# 点击按钮进行验证
time.sleep(1)
driver.find_element(By.CLASS_NAME,"geetest_radar_tip").click()
content=driver.find_elements(By.CSS_SELECTOR,'#password-captcha-box > div.geetest_holder.geetest_wind.geetest_radar_success > div.geetest_btn > div.geetest_ghost_success.geetest_success_animate > div > div.geetest_success_radar_tip > span.geetest_success_radar_tip_content')
if content:
if '验证成功' in content[0].text:
driver.find_element(By.CSS_SELECTOR,'#login > div > div.zbj-form-item.login-form-button > button').click()
# 获取缺口图,滑块图和完整图
bg_path,slice_path,fullbg_path=canvas()
#dis=缺口图的距离-滑块图的距离
dis=get_distance(bg_path,slice_path,fullbg_path)
print(dis)
count=3
while count>0:
#模拟人工操作
tracks=get_track(dis)
#seleium操作,按住滑动条,滑动并且松开鼠标
move(tracks)
bok=driver.find_element(By.XPATH,'//*[@id="password-captcha-box"]/div[2]/div[2]/div[2]/div/div[2]/span[1]').text
if bok:
print('校验成功',bok)
driver.find_element(By.XPATH,'//*[@id="login"]/div/div[5]/button').click()
# driver.find_element(By.CLASS_NAME,'j-uc-ad-force-qiwei-close').click()
break
else:
count+=1
bok_1=driver.find_element(By.CLASS_NAME,"geetest_reset_tip_content")
bok_2=bok_1.text
# 出现被怪兽吃掉 网络不给力
if '请点击重试' in bok_2:
bok_1.click()
# 获取缺口图,滑块图和完整图
bg_path, slice_path, fullbg_path = canvas()
dis1 = get_distance(bg_path, slice_path, fullbg_path)
tracks = get_track(dis1)
print(dis1)
move(tracks)
time.sleep(3)
# driver.close()
自己的密码包:xx.py
USER='xxxx'
PASSWORD='xxxx'
具体步骤看我上个博客。唉,路漫漫其修远兮,吾将上下而求索。