这篇文章主要介绍了Python如何破解滑动验证码的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python如何破解滑动验证码文章都会有所收获,下面我们一起来看看吧。

滑动验证码破解思路

对于这类验证,如果我们直接模拟表单请求,繁琐的认证参数与认证流程会让你蛋碎一地,我们可以用selenium驱动浏览器来解决这个问题,大致分为以下几个步骤

1、输入用户名,密码

2、点击按钮验证,弹出没有缺口的图

3、获得没有缺口的图片

4、点击滑动按钮,弹出有缺口的图

5、获得有缺口的图片

6、对比两张图片,找出缺口,即滑动的位移

7、按照人的行为行为习惯,把总位移切成一段段小的位移

8、按照位移移动

9、完成登录

实现

位移移动的代码实现

defget_track(distance):'''拿到移动轨迹,模仿人的滑动行为,先匀加速后匀减速匀变速运动基本公式:①v=v0+at②s=v0t+(1/2)at²③v²-v0²=2as:paramdistance:需要移动的距离:return:存放每0.2秒移动的距离'''#初速度v=0#单位时间为0.2s来统计轨迹,轨迹即0.2内的位移t=0.1#位移/轨迹列表,列表内的一个元素代表0.2s的位移tracks=[]#当前的位移current=0#到达mid值开始减速mid=distance*4/5distance+=10#先滑过一点,最后再反着滑动回来whilecurrent<distance:ifcurrent<mid:#加速度越小,单位时间的位移越小,模拟的轨迹就越多越详细a=2#加速运动else:a=-3#减速运动#初速度v0=v#0.2秒时间内的位移s=v0*t+0.5*a*(t**2)#当前的位置current+=s#添加到轨迹列表tracks.append(round(s))#速度已经达到v,该速度作为下次的初速度v=v0+a*t#反着滑动到大概准确位置foriinrange(3):tracks.append(-2)foriinrange(4):tracks.append(-1)returntracks对比两张图片,找出缺口

defget_distance(image1,image2):'''拿到滑动验证码需要移动的距离:paramimage1:没有缺口的图片对象:paramimage2:带缺口的图片对象:return:需要移动的距离'''#print('size',image1.size)threshold=50foriinrange(0,image1.size[0]):#260forjinrange(0,image1.size[1]):#160pixel1=image1.getpixel((i,j))pixel2=image2.getpixel((i,j))res_R=abs(pixel1[0]-pixel2[0])#计算RGB差res_G=abs(pixel1[1]-pixel2[1])#计算RGB差res_B=abs(pixel1[2]-pixel2[2])#计算RGB差ifres_R>thresholdandres_G>thresholdandres_B>threshold:returni#需要移动的距离获得图片

defmerge_image(image_file,location_list):"""拼接图片:paramimage_file::paramlocation_list::return:"""im=Image.open(image_file)im.save('code.jpg')new_im=Image.new('RGB',(260,116))#把无序的图片切成52张小图片im_list_upper=[]im_list_down=[]#print(location_list)forlocationinlocation_list:#print(location['y'])iflocation['y']==-58:#上半边im_list_upper.append(im.crop((abs(location['x']),58,abs(location['x'])+10,116)))iflocation['y']==0:#下半边im_list_down.append(im.crop((abs(location['x']),0,abs(location['x'])+10,58)))x_offset=0foriminim_list_upper:new_im.paste(im,(x_offset,0))#把小图片放到新的空白图片上x_offset+=im.size[0]x_offset=0foriminim_list_down:new_im.paste(im,(x_offset,58))x_offset+=im.size[0]new_im.show()returnnew_imdefget_image(driver,div_path):'''下载无序的图片然后进行拼接获得完整的图片:paramdriver::paramdiv_path::return:'''time.sleep(2)background_images=driver.find_elements_by_xpath(div_path)location_list=[]forbackground_imageinbackground_images:location={}result=re.findall('background-image:url("(.*?)");background-position:(.*?)px(.*?)px;',background_image.get_attribute('style'))#print(result)location['x']=int(result[0][1])location['y']=int(result[0][2])image_url=result[0][0]location_list.append(location)print('==================================')image_url=image_url.replace('webp','jpg')#'替换urlhttp://static.geetest.com/pictures/gt/579066de6/579066de6.webp'image_result=requests.get(image_url).content#withopen('1.jpg','wb')asf:#f.write(image_result)image_file=BytesIO(image_result)#是一张无序的图片image=merge_image(image_file,location_list)returnimage按照位移移动

print('第一步,点击滑动按钮')ActionChains(driver).click_and_hold(on_element=element).perform()#点击鼠标左键,按住不放time.sleep(1)print('第二步,拖动元素')fortrackintrack_list:ActionChains(driver).move_by_offset(xoffset=track,yoffset=0).perform()#鼠标移动到距离当前位置(x,y)ifl<100:ActionChains(driver).move_by_offset(xoffset=-2,yoffset=0).perform()else:ActionChains(driver).move_by_offset(xoffset=-5,yoffset=0).perform()time.sleep(1)print('第三步,释放鼠标')ActionChains(driver).release(on_element=element).perform()详细代码

fromseleniumimportwebdriverfromselenium.webdriver.support.uiimportWebDriverWait#等待元素加载的fromselenium.webdriver.common.action_chainsimportActionChains#拖拽fromselenium.webdriver.supportimportexpected_conditionsasECfromselenium.common.exceptionsimportTimeoutException,NoSuchElementExceptionfromselenium.webdriver.common.byimportByfromPILimportImageimportrequestsimporttimeimportreimportrandomfromioimportBytesIOdefmerge_image(image_file,location_list):"""拼接图片:paramimage_file::paramlocation_list::return:"""im=Image.open(image_file)im.save('code.jpg')new_im=Image.new('RGB',(260,116))#把无序的图片切成52张小图片im_list_upper=[]im_list_down=[]#print(location_list)forlocationinlocation_list:#print(location['y'])iflocation['y']==-58:#上半边im_list_upper.append(im.crop((abs(location['x']),58,abs(location['x'])+10,116)))iflocation['y']==0:#下半边im_list_down.append(im.crop((abs(location['x']),0,abs(location['x'])+10,58)))x_offset=0foriminim_list_upper:new_im.paste(im,(x_offset,0))#把小图片放到新的空白图片上x_offset+=im.size[0]x_offset=0foriminim_list_down:new_im.paste(im,(x_offset,58))x_offset+=im.size[0]new_im.show()returnnew_imdefget_image(driver,div_path):'''下载无序的图片然后进行拼接获得完整的图片:paramdriver::paramdiv_path::return:'''time.sleep(2)background_images=driver.find_elements_by_xpath(div_path)location_list=[]forbackground_imageinbackground_images:location={}result=re.findall('background-image:url("(.*?)");background-position:(.*?)px(.*?)px;',background_image.get_attribute('style'))#print(result)location['x']=int(result[0][1])location['y']=int(result[0][2])image_url=result[0][0]location_list.append(location)print('==================================')image_url=image_url.replace('webp','jpg')#'替换urlhttp://static.geetest.com/pictures/gt/579066de6/579066de6.webp'image_result=requests.get(image_url).content#withopen('1.jpg','wb')asf:#f.write(image_result)image_file=BytesIO(image_result)#是一张无序的图片image=merge_image(image_file,location_list)returnimagedefget_track(distance):'''拿到移动轨迹,模仿人的滑动行为,先匀加速后匀减速匀变速运动基本公式:①v=v0+at②s=v0t+(1/2)at²③v²-v0²=2as:paramdistance:需要移动的距离:return:存放每0.2秒移动的距离'''#初速度v=0#单位时间为0.2s来统计轨迹,轨迹即0.2内的位移t=0.2#位移/轨迹列表,列表内的一个元素代表0.2s的位移tracks=[]#当前的位移current=0#到达mid值开始减速mid=distance*7/8distance+=10#先滑过一点,最后再反着滑动回来#a=random.randint(1,3)whilecurrent<distance:ifcurrent<mid:#加速度越小,单位时间的位移越小,模拟的轨迹就越多越详细a=random.randint(2,4)#加速运动else:a=-random.randint(3,5)#减速运动#初速度v0=v#0.2秒时间内的位移s=v0*t+0.5*a*(t**2)#当前的位置current+=s#添加到轨迹列表tracks.append(round(s))#速度已经达到v,该速度作为下次的初速度v=v0+a*t#反着滑动到大概准确位置foriinrange(4):tracks.append(-random.randint(2,3))foriinrange(4):tracks.append(-random.randint(1,3))returntracksdefget_distance(image1,image2):'''拿到滑动验证码需要移动的距离:paramimage1:没有缺口的图片对象:paramimage2:带缺口的图片对象:return:需要移动的距离'''#print('size',image1.size)threshold=50foriinrange(0,image1.size[0]):#260forjinrange(0,image1.size[1]):#160pixel1=image1.getpixel((i,j))pixel2=image2.getpixel((i,j))res_R=abs(pixel1[0]-pixel2[0])#计算RGB差res_G=abs(pixel1[1]-pixel2[1])#计算RGB差res_B=abs(pixel1[2]-pixel2[2])#计算RGB差ifres_R>thresholdandres_G>thresholdandres_B>threshold:returni#需要移动的距离defmain_check_code(driver,element):"""拖动识别验证码:paramdriver::paramelement::return:"""image1=get_image(driver,'//div[@class="gt_cut_bggt_show"]/div')image2=get_image(driver,'//div[@class="gt_cut_fullbggt_show"]/div')#图片上缺口的位置的x坐标#2对比两张图片的所有RBG像素点,得到不一样像素点的x值,即要移动的距离l=get_distance(image1,image2)print('l=',l)#3获得移动轨迹track_list=get_track(l)print('第一步,点击滑动按钮')ActionChains(driver).click_and_hold(on_element=element).perform()#点击鼠标左键,按住不放time.sleep(1)print('第二步,拖动元素')fortrackintrack_list:ActionChains(driver).move_by_offset(xoffset=track,yoffset=0).perform()#鼠标移动到距离当前位置(x,y)     time.sleep(0.002)#ifl>100:ActionChains(driver).move_by_offset(xoffset=-random.randint(2,5),yoffset=0).perform()time.sleep(1)print('第三步,释放鼠标')ActionChains(driver).release(on_element=element).perform()time.sleep(5)defmain_check_slider(driver):"""检查滑动按钮是否加载:paramdriver::return:"""whileTrue:try:driver.get('http://www.cnbaowen.net/api/geetest/')element=WebDriverWait(driver,30,0.5).until(EC.element_to_be_clickable((By.CLASS_NAME,'gt_slider_knob')))ifelement:returnelementexceptTimeoutExceptionase:print('超时错误,继续')time.sleep(5)if__name__=='__main__':try:count=6#最多识别6次driver=webdriver.Chrome()#等待滑动按钮加载完成element=main_check_slider(driver)whilecount>0:main_check_code(driver,element)time.sleep(2)try:success_element=(By.CSS_SELECTOR,'.gt_holder.gt_ajax_tip.gt_success')#得到成功标志print('suc=',driver.find_element_by_css_selector('.gt_holder.gt_ajax_tip.gt_success'))success_images=WebDriverWait(driver,20).until(EC.presence_of_element_located(success_element))ifsuccess_images:print('成功识别!!!!!!')count=0breakexceptNoSuchElementExceptionase:print('识别错误,继续')count-=1time.sleep(2)else:print('toomanyattemptcheckcode')exit('退出程序')finally:driver.close()

关于“Python如何破解滑动验证码”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Python如何破解滑动验证码”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。