python day07

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

 

 
posted @ 2019-06-22 10:26  有生-L  阅读(230)  评论(0编辑  收藏  举报