滑动验证码解决方案
Posted foryouos
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了滑动验证码解决方案相关的知识,希望对你有一定的参考价值。
滑动验证--中国保温网联系
# 两张图片,一张无缺口,一张有缺口,通过对比两张图片的像素点,找到缺口的位置(x)
# 获取两张图片
#获取坐标
# 模拟滑动,单一机器滑动,会以为
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains #滑动动作
from PIL import Image # 处理图片
from io import BytesIO
import re # 使用正则获取style的url
import requests # 获取url的图片信息
import time
import random # 使用随机函数进行设置速度
# 保存图片
def get_imge(driver,div_class,name):
bg_imgs = driver.find_elements_by_class_name(div_class)
#img_url =''
location_list =[]
for imge in bg_imgs:
#print(imge.get_attribute("style")) # 获得图片style信息
location = {}
image_url = re.findall(r'background-image: url\("(.*?)"\); background-position: (.*?)px (.*?)px;',
imge.get_attribute("style"))[0][0]
location['x'] = re.findall(r'background-image: url\("(.*?)"\); background-position: (.*?)px (.*?)px;',
imge.get_attribute("style"))[0][1]
location['y'] = re.findall(r'background-image: url\("(.*?)"\); background-position: (.*?)px (.*?)px;',
imge.get_attribute("style"))[0][2]
#print(image_url,location['x'],location['y']) #获取上面检索的url,坐标
location_list.append(location)
response = requests.get(image_url).content
image_content =BytesIO(response) # 像文件一样读取二进制文件
#image.show()
image = get_meige_image(image_content,location_list,name)
image.save("{}.jpg".format(name))
return image
# 获得像素点
def get_meige_image(image_content,location_list,name):
#拼接图片
image = Image.open(image_content)
image_list_up =[]
image_list_down =[]
for location in location_list:
if int(location['y']) ==-58:
image_list_up.append(image.crop((abs(int(location['x'])),58,abs(int(location['x']))+10,116)))
if int(location['y']) ==0:
image_list_down.append(image.crop((abs(int(location['x'])),0,abs(int(location['x']))+10,58)))
new_image = Image.new('RGB',(260,116))
postion_x= 0
for image in image_list_up:
new_image.paste(image,(postion_x,0))
postion_x +=10
postion_x = 0
for image in image_list_down:
new_image.paste(image, (postion_x, 58))
postion_x += 10
#new_image.show() # 获取两张图片
return new_image
#返回不同的x点
def get_diff_location(image1,image2):
'''
通过对比图像找到缺口位置
:param image1:
:param image2:
:return:
'''
for y in range(1, 115):
for x in range(1,259):
# 判断成立,表示这个点,两张图的像素点
if is_similar(image1,image2,x,y) == False:
return x
# 获取不相同点
def is_similar(image1,image2,x,y):
pixel1 = image1.getpixel((x,y))
pixel2 = image2.getpixel((x,y)) # 元组
for i in range(0,3):
if (abs(pixel1[i] - pixel2[i]) >= 50):
return False
return True
# 模拟滑动,使网站难以识别是认为运动
def get_take(x):
'''
模拟匀加速后匀减速运动,加上来回滑动
:param x:
:return:
'''
v = 0#初速度
t = 1
temp =0
tracks=[]
mid = x*5 / 8
x = x + 10
while temp < x:
if temp < mid :
a =random.randint(1,3)
else:
a = -random.randint(2,4)
v0 = v
s = v0 * t + (1/2)* a * (t ** 2)
tracks.append(round(s))
temp += s
v = v0 + a*t
for i in range(4):
tracks.append(-random.randint(6,10)) # 此数字可以有变化进行调整,根据规则,当网站识别你为机器人时,它会使误差增大,从而失败,尽量不要使网站识别出来
return tracks
def main(driver,elem):
image1= get_imge(driver,'gt_cut_fullbg_slice','fullbg')
image2 = get_imge(driver, 'gt_cut_bg_slice','bg')
x = get_diff_location(image1,image2)
print("应该移动的坐标:{}".format(x)) #输出滑到的x点
# 最基本的滑动轨迹,会检验出来是电脑自动滑的,怪物已经吃了拼图
ActionChains(driver).click_and_hold(elem).perform()
#模拟匀加速运动
tracks = get_take(x)
for x1 in tracks:
ActionChains(driver).move_by_offset(xoffset=x1,yoffset=0).perform()
#ActionChains(driver).move_by_offset(xoffset=-20,yoffset=0).perform() #进行局部调整进行对准
ActionChains(driver).release(elem).perform()
time.sleep(1)
if __name__ == "__main__":
driver = webdriver.Chrome()
# 获得url
driver.get("http://www.cnbaowen.net/api/geetest/")
try:
count=5
# 时间缓冲
wait = WebDriverWait(driver, 10)
# 定位到滑块
elem = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "gt_slider_knob")))
while count > 0:
main(driver,elem)
try:
success = wait.until(EC.visibility_of((By.XPATH,"//div[@class='gt_slider']/div[@class='gt_ajax_tip gt_success'])")))
if success:
print("success")
break
except Exception as e:
print("error")
time.sleep(1)
finally:
driver.quit()
以B站登陆为例子
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains #滑动动作
from PIL import Image # 处理图片
from io import BytesIO
import re # 使用正则获取style的url
import requests # 获取url的图片信息
import time
import random # 使用随机函数进行设置速度
#账号密码输入
def login(user,passwd):
username =wait.until(EC.presence_of_element_located((By.ID,"login-username")))
username.send_keys(user)
password =wait.until(EC.presence_of_element_located((By.ID,"login-passwd")))
password.send_keys(passwd)
time.sleep(2)
#双击登录
element =driver.find_element_by_xpath("//a[@class='btn btn-login']")
ActionChains(driver).double_click(element).perform()
#设置延时
time.sleep(3)
def get_image():
geetest =wait.until(EC.presence_of_element_located((By.XPATH,"//canvas[@class='geetest_canvas_slice geetest_absolute']")))
geetest.screenshot("bg.png")
image_bg = Image.open("bg.png")
js = 'var change = document.getElementsByClassName("geetest_canvas_fullbg"); change[0].style = "display: block;"'
driver.execute_script(js)
time.sleep(2)
geetest_canvas_fullbg = wait.until(EC.presence_of_element_located((By.CLASS_NAME,"geetest_canvas_fullbg ")))
geetest_canvas_fullbg.screenshot("fullbg.png")
image_fullbg = Image.open("fullbg.png")
return image_bg,image_fullbg
#返回不同的x点
def get_diff_location(image1,image2):
'''
通过对比图像找到缺口位置
:param image1:
:param image2:
:return:
'''
for x in range(60, image1.size[0]):
for y in range(1,image1.size[1]):
# 判断成立,表示这个点,两张图的像素点
if is_similar(image1,image2,x,y) == False:
return x
# 获取不相同点
def is_similar(image1,image2,x,y):
pixel1 = image1.getpixel((x,y))
pixel2 = image2.getpixel((x,y)) # 元组
for i in range(0,3):
if (abs(pixel1[i] - pixel2[i]) >= 50):
return False
return True
# 模拟滑动,使网站难以识别是认为运动
def get_take(x):
'''
模拟匀加速后匀减速运动,加上来回滑动
:param x:
:return:
'''
v = 0#初速度
t = 1
temp =0
tracks=[]
mid = x*5 / 8
x = x + 10
while temp < x:
if temp < mid :
a =random.randint(1,3)
else:
a = -random.randint(2,4)
v0 = v
s = v0 * t + (1/2)* a * (t ** 2)
tracks.append(round(s))
temp += s
v = v0 + a*t
for i in range(4):
tracks.append(-random.randint(2,4)) # 此数字可以有变化进行调整,根据规则,当网站识别你为机器人时,它会使误差增大,从而失败,尽量不要使网站识别出来
return tracks
def main(driver,elem):
image_bg,image_fullbg = get_image()
x = get_diff_location(image_bg,image_fullbg)
#print("应该移动的坐标:{}".format(x)) #输出滑到的x点
# 最基本的滑动轨迹,会检验出来是电脑自动滑的,怪物已经吃了拼图
ActionChains(driver).click_and_hold(elem).perform()
#模拟匀加速运动
tracks = get_take(x-7) #获取滑块的初始位置,要减去
for x1 in tracks:
ActionChains(driver).move_by_offset(xoffset=x1,yoffset=0).perform()
#ActionChains(driver).move_by_offset(xoffset=-20,yoffset=0).perform() #进行局部调整进行对准
ActionChains(driver).release(elem).perform()
time.sleep(1)
try:
driver.find_element_by_class_name("1111")
except:
driver.refresh()
main()
if __name__ == '__main__':
driver = webdriver.Chrome()
driver.get("https://passport.bilibili.com/login")
wait = WebDriverWait(driver, 10)
login("xxxxxxxxxxx","xxxxxxxxx")
elem = wait.until(EC.presence_of_element_located((By.CLASS_NAME,"geetest_slider_button")))
main(driver,elem)
以上是关于滑动验证码解决方案的主要内容,如果未能解决你的问题,请参考以下文章