day07

今日内容:
1、破解极验滑动验证
2、BeautifulSoup解析库

 课堂内容如下

''''''
'''
破解极验滑动验证
破解极验滑动验证
博客园登录url:
https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F

代码逻辑:
1、输入用户名与密码,并点击登录
2、弹出滑动验证,获取有缺口与完整的图片
3、通过像素点进行比对,获取滑动位移距离
4、模拟人的行为轨迹
5、开始滑动

'''
from selenium import webdriver # 用来驱动浏览器的
from selenium.webdriver import ActionChains # 破解滑动验证码的时候用的 可以拖动图片
import time
from PIL import Image # pip3 install pillow
import random

# 截图图片函数
def cut_image(driver):
# 获取整个页面图片,图片名字为'snap.png'
driver.save_screenshot('snap.png')

# 获取滑动小画图
image = driver.find_element_by_class_name('geetest_canvas_img')
print(image.location)
print(image.size)

# 获取小图片的左上右下的位置
left = image.location['x']
top = image.location['y']
right = left + image.size['width']
buttom = top + image.size['height']
print(left, top, right, buttom)

# 调用open方法打开全屏图片并赋值给image_obj对象
image_obj = Image.open('snap.png')

# 通过image_obj对象对小图片进行截取
# box: The crop rectangle, as a (left, upper, right, lower)-tuple.
img = image_obj.crop((left, top, right, buttom))
# 打开截取后的小图片
# img.show()
return img

# 获取完整图片
def get_image1(driver):
time.sleep(2)

# 修改document文档树,把完整图片的display属性修改为block
js_code = '''
var x = document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display = "block";
'''

# 执行js代码
driver.execute_script(js_code)

# 截取图片
image = cut_image(driver)

return image

# 获取有缺口图片
def get_image2(driver):
time.sleep(2)

# 修改document文档树,把完整图片的display属性修改为block
js_code = '''
var x = document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display = "none";
'''

# 执行js代码
driver.execute_script(js_code)

# 截取图片
image = cut_image(driver)

return image

# 获取滑块滑动距离
def get_distance(image1, image2):
# 小滑块右侧位置
start = 60

# 像素差
num = 60
print(image1.size)
for x in range(start, image1.size[0]):
for y in range(image1.size[1]):

# 获取image1完整图片每一个坐标的像素点
rgb1 = image1.load()[x, y]

# 获取image2缺口图片每一个坐标的像素点
rgb2 = image2.load()[x, y]
# (60, 86, 40) (60, 86, 40) rgb
print(rgb1, rgb2)

# abs获取绝对值, 像素点比较的值
r = abs(rgb1[0] - rgb2[0])
g = abs(rgb1[1] - rgb2[1])
b = abs(rgb1[2] - rgb2[2])

# 如果条件成立,则找到缺口位置
if not (r < num and g < num and b < num):
# 有误差 - 7像素
return x - 7

# 模拟人的滑动轨迹
def get_strck_move(distance):
distance += 20

'''
滑动行为轨迹
加速公式:
v = v0 + a * t

路程公式:
s = v0 * t + 0.5 * a * (t ** 2)
'''

# 初速度
v0 = 0

# 时间
t = 0.2

# 位置
s = 0

# 滑动轨迹列表 向前滑动列表
move_list = []

# 中间值,作为加减速度的位置
mid = distance / 5 * 3

# 加减速度列表
v_list = [1, 2, 3, 4]

# 循环位移
while s < distance:
if s < mid:
# 随机获取一个加速度
a = v_list[random.randint(0, len(v_list) - 1)]

else:
# 随机获取一个减速度
a = -v_list[random.randint(0, len(v_list) - 1)]

'''
匀加速\减速运行
v = v0 + a * t

位移:
s = v * t + 0.5 * a * (t**2)
'''
# 获取初始速度
v = v0

# 路程公式:
s1 = v * t + 0.5 * a * (t ** 2)
s1 = round(s1) # 取整

# 加速公式:
# v = v0 + a * t
m_v = v + a * t

# 把当前加/减速度赋值给初始速度,以便下一次计算
v0 = m_v

# 把位移添加到滑动列表中
move_list.append(s1)

# 修改滑动初始距离
s += s1

# 后退列表, 自定义后退滑动轨迹,必须是负值
back_list = [-1, -1, -2, -3, -2, -1, -1, -2, -3, -2, -1, -1]

return {'move_list': move_list, 'back_list': back_list}

def main():
driver = webdriver.Chrome(r'D:\BaiduNetdiskDownload\chromedriver_win32\chromedriver.exe')
driver.implicitly_wait(10)
try:
driver.get('https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F')

# 1、输入用户名与密码,并点击登录
user_input = driver.find_element_by_id('LoginName')
user_input.send_keys('_tank_')
time.sleep(0.2)

pwd_input = driver.find_element_by_id('Password')
pwd_input.send_keys('k46709394.')
time.sleep(2)

login_submit = driver.find_element_by_id('submitBtn')
login_submit.click()

# 2、获取完整的图片
image1 = get_image1(driver)

# 3、获取有缺口图片
image2 = get_image2(driver)

# 4、比对两张图片,获取滑动距离
distance = get_distance(image1, image2)
print(distance)

# 5、模拟人的滑动轨迹
move_dict = get_strck_move(distance)
# 获取前进滑动轨迹
move_list = move_dict['move_list']
# 获取后退滑动轨迹
back_list = move_dict['back_list']

# 6、开始滑动
move_tag = driver.find_element_by_class_name('geetest_slider_button')
# 点击摁住滑动按钮
ActionChains(driver).click_and_hold(move_tag).perform()

# 向前滑动
for move in move_list:
ActionChains(driver).move_by_offset(xoffset=move, yoffset=0).perform()
time.sleep(0.1)

time.sleep(0.1)

# 向后滑动
for back in back_list:
ActionChains(driver).move_by_offset(xoffset=back, yoffset=0).perform()
time.sleep(0.1)

# 制作微妙晃动
ActionChains(driver).move_by_offset(xoffset=3, yoffset=0).perform()
ActionChains(driver).move_by_offset(xoffset=-3, yoffset=0).perform()

time.sleep(0.1)

# 释放滑动按钮
ActionChains(driver).release().perform()

time.sleep(100)

finally:
driver.close()

if __name__ == '__main__':
main()

posted @ 2019-06-21 22:20  时无英雄  阅读(138)  评论(0编辑  收藏  举报