2019.6.19

今日内容

破解极验的滑动验证

代码如下:

  1 '''
  2 博客园登录url:
  3     https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F
  4 1、输入用户名与密码,并点击登录
  5 2、弹出滑动验证,获取有缺口与完整的图片
  6 3、通过像素点进行对比,获取滑动距离位移
  7 4、模拟人的行为轨迹
  8 5、开始滑动
  9 
 10 '''
 11 
 12 from selenium import webdriver
 13 from selenium.webdriver import ActionChains
 14 import  time
 15 from PIL import Image
 16 import random
 17 driver = webdriver.Chrome()
 18 
 19 try:
 20     # 截取图片函数
 21     def cut_image(driver):
 22         # 获取整个页面图片,图片名字为snap
 23         driver.save_screenshot('snap.png')
 24 
 25         # 获取滑动小图片
 26         image = driver.find_element_by_class_name("geetest_canvas_img")
 27         print(image.location)
 28         print(image.size)
 29 
 30         # 获取小图片的左、上、右、下位置
 31         left = image.location['x']
 32         top = image.location['y']
 33         right = left + image.size['width']
 34         bottom = top + image.size['height']
 35 
 36         print(left, top, right, bottom)
 37 
 38         # 调用open方法打开全屏图片并赋值给image_obj对象
 39         image_obj = Image.open('snap.png')
 40 
 41         # 通过image_obj对象对小图片进行截图
 42         img = image_obj.crop((left, top, right, bottom))
 43 
 44         # 打开截取后的小图片
 45         # img.show()
 46 
 47         return img
 48 
 49 
 50     # 获取完整图片
 51     def get_image1(driver):
 52 
 53         time.sleep(2)
 54         # 修改document文档树,吧完整图片的display属性修改为block
 55         js_code = '''
 56             var x=document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display="block";
 57 
 58         '''
 59         # 执行js代码
 60         driver.execute_script(js_code)
 61 
 62         # 截取图片
 63         image = cut_image(driver)
 64         return image
 65 
 66 
 67     # 获取有缺口图片
 68     def get_image2(driver):
 69         time.sleep(5)
 70         # 修改document文档树,吧完整图片的display属性修改为block
 71         js_code = '''
 72             var x=document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display="none";
 73 
 74         '''
 75         # 执行js代码
 76         driver.execute_script(js_code)
 77 
 78         # 截取图片
 79         image = cut_image(driver)
 80         return image
 81 
 82 
 83     # 获取滑块距离
 84     def get_distance(image1, image2):
 85         # 小滑块右侧距离
 86         start = 60
 87 
 88         # 像素差
 89         num = 60
 90 
 91         for x in range(start, image1.size[0]):
 92             for y in range(image1.size[1]):
 93                 # 获取image1完整图片的每一个坐标的像素点
 94                 rgb1 = image1.load()[x, y]  # (60,86,60)
 95                 # 获取image2缺口图片的每一个坐标的像素点
 96                 rgb2 = image2.load()[x, y]  # (60,86,60)
 97                 print(rgb1, rgb2)
 98 
 99                 # abs获取绝对值,像素点比较的值
100                 r = abs(rgb1[0] - rgb2[0])
101                 g = abs(rgb1[1] - rgb2[1])
102                 b = abs(rgb1[2] - rgb2[2])
103 
104                 if not (r < num and g < num and b < num):
105                     return x - 7
106 
107 
108     # 模拟人的滑动轨迹
109     def get_strck_move(distance):
110         distance += 20
111         # 初速度
112         v0 = 0
113         # 时间
114         t = 0.2
115 
116         # 位置
117         s = 0
118 
119         # 滑动轨迹列表
120         move_list = []
121 
122         # 中间值,作为加减速度的位置
123         mid = distance / 5 * 3
124 
125         # 加减速度列表
126         v_list = [1, 2, 3, 4]
127 
128         # 循环位移
129         while s < distance:
130             if s < mid:
131                 # 随机获取一个加速度
132                 a = v_list[random.randint(0, len(v_list) - 1)]
133             else:
134                 # 随机获取一个减速度
135                 a = -v_list[random.randint(0, len(v_list) - 1)]
136 
137             v = v0
138 
139             # 路程公式
140             # s=v0*t+0.5*a*(t**2)
141 
142             s1 = v * t + 0.5 * a * (t ** 2)
143             s1 = round(s1)  # 取整
144 
145             # 加速度公式
146             # v=v0+a*t
147             m_v = v + a * t
148 
149             # 把当前加/减速度赋值给初始速度,以便下一次计算
150             v0 = m_v
151 
152             # 把位移添加到滑动列表中
153             move_list.append(s1)
154 
155             # 修改滑动距离
156             s += s1
157 
158         # 后退列表,自定义后退滑动轨迹,必须是负值
159         back_list = [-1, -1, -2, -3, -2, -1, -1, -2, -3, -2, -1, -1]
160 
161         return {'move_list': move_list, 'back_list': back_list}
162 
163 
164     def main():
165 
166         # 隐式等待,写在get请求之前###若为显示等待,写在get请求之后
167         driver.implicitly_wait(10)
168 
169         driver.get('https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F')
170 
171         # 1、输入用户名与密码,并点击登录
172         user_input = driver.find_element_by_id('LoginName')
173         user_input.send_keys('Hi!Superman')
174         time.sleep(0.2)
175 
176         pwd_input = driver.find_element_by_id('Password')
177         pwd_input.send_keys('********')
178         time.sleep(2)
179 
180         login_submit = driver.find_element_by_id('submitBtn')
181         login_submit.click()
182 
183         # 2、获取完整图片
184         image1 = get_image1(driver)
185 
186         # 3、获取有缺口的图片
187         image2 = get_image2(driver)
188         time.sleep(10)
189 
190         # 对比两张图片,获取滑动距离
191         distance = get_distance(image1, image2)
192         print(distance)
193 
194         # 模拟人的滑动轨迹
195         move_dict = get_strck_move(distance)
196 
197         # 获取前进滑动轨迹
198         move_list = move_dict['move_list']
199         # 获取后退滑动轨迹
200         back_list = move_dict['back_list']
201 
202         # 6、开始滑动
203         move_tag = driver.find_element_by_class_name('geetest_slider_button')
204         # 点击按住滑动按钮
205         ActionChains(driver).click_and_hold(move_tag).perform()
206 
207         # 向前滑动
208         for move in move_list:
209             ActionChains(driver).move_by_offset(xoffset=move, yoffset=0).perform()
210             time.sleep(0.2)
211 
212         # 向后滑动
213         for back in back_list:
214             ActionChains(driver).move_by_offset(xoffset=back, yoffset=0).perform()
215             time.sleep(0.2)
216 
217         # 制作微妙晃动
218         ActionChains(driver).move_by_offset(xoffset=3, yoffset=0).perform()
219         ActionChains(driver).move_by_offset(xoffset=-3, yoffset=0).perform()
220         time.sleep(0.2)
221 
222         # 释放滑动按钮
223         ActionChains(driver).release().perform()
224 
225 
226 finally:
227     driver.close()
228 
229 
230 if __name__ == '__main__':
231     main()

 

posted @ 2019-06-21 08:41  鸡肉串  阅读(199)  评论(0编辑  收藏  举报