当前位置: 首页 > news >正文

取消网站备案号最新国际形势最新消息

取消网站备案号,最新国际形势最新消息,宝石汇网站,重庆公司有哪些| 完美是不可能的#xff0c;加个震惊#xff01;Python破解BiliBili滑块验证码#xff0c;完美避开人机识别#xff0c;可以有 准备工作 B站登录页 https://passport.bilibili.com/loginpython3pip install selenium #xff08;webdriver框架#xff09;pip install P… | 完美是不可能的加个震惊Python破解BiliBili滑块验证码完美避开人机识别可以有 准备工作 B站登录页 https://passport.bilibili.com/loginpython3pip install selenium webdriver框架pip install PIL 图片处理chrome driverhttp://chromedriver.storage.googleapis.com/index.htmlfirefox driverhttps://github.com/mozilla/geckodriver/releasesB站的滑块验证码如上。 这类验证码可以使用 selenium 操作浏览器拖拽滑块来进行破解难点两个一个如何确定拖拽到的位置另一个是避开人机识别反爬虫。 确定滑块验证码需要拖拽的位移距离 有三种方式 人工智能机器学习确定滑块位置通过完整图片与缺失滑块的图片进行像素对比确定滑块位置边缘检测算法确定位置 各有优缺点。人工智能机器学习确定滑块位置需要进行训练比较麻烦也可以看是否存在在线api可以调用。以下介绍其他两种方式。 对比完整图片与缺失滑块的图片 | 仅介绍本文不进行实现。对于B站来说是准确率最高的方式100%但不能保证未来B站的滑块验证升级导致不可用。 B站的滑块验证模块一共有三张图片完整图、缺失滑块图、滑块图都是由画布绘制出的。类似于 完整图 缺失滑块图 滑块图 HTML代码类似于 div classgeetest_canvas_img geetest_absolute styledisplay: block; div classgeetest_slicebg geetest_absolutecanvas classgeetest_canvas_bg geetest_absolute height160 width260/canvascanvas classgeetest_canvas_slice geetest_absolute width260 height160/canvas /div canvas classgeetest_canvas_fullbg geetest_fade geetest_absolute height160 width260 styledisplay: none;/canvas /div 12345678 只需要通过selenium获取画布元素执行js拿到画布像素遍历完整图和缺失滑块图的像素一旦获取到差异需要允许少许像素误差像素矩阵x轴方向即是滑块位置。 另外由于滑块图距离画布坐标原点有距离还需要减去这部分距离。 最后使用 selenium 拖拽即可。 边缘检测算法确定位置 | 滑块基本上是个方形通过算法确定方形起始位置即可。 介绍两种方式 滑块是方形的存在垂直与水平的边该边在缺失滑块图中基本都是灰黑的。遍历像素找到基本都是灰黑的边即可。缺失滑块图中滑块位置是灰黑封闭的。通过算法可以找到封闭区域大小与滑块相近即是滑块需要拖拽到的位置。 第二种实现起来有些复杂不进行实现了。 下面是第一种实现方式只实现了垂直边的检测水平边检测原理一致会存在检测不出或错误的情况使用时需要换一张验证码。也可能存在检测出的边是另一条因为B站的滑块不是长方形存在弧形边那么需要减去滑块宽度 class VeriImageUtil():def __init__(self):self.defaultConfig {grayOffset: 20,opaque: 1,minVerticalLineCount: 30}self.config copy.deepcopy(self.defaultConfig)def updateConfig(self, config):# temp copy.deepcopy(config)for k in self.config:if k in config.keys():self.config[k] config[k]def getMaxOffset(self, *args):# 计算偏移平均值最大的数av sum(args) / len(args)maxOffset 0for a in args:offset abs(av - a)if offset maxOffset:maxOffset offsetreturn maxOffsetdef isGrayPx(self, r, g, b):# 是否是灰度像素点允许波动offsetreturn self.getMaxOffset(r, g, b) self.config[grayOffset]def isDarkStyle(self, r, g, b):# 灰暗风格return r 128 and g 128 and b 128def isOpaque(self, px):# 不透明return px[3] 255 * self.config[opaque]def getVerticalLineOffsetX(self, bgImage):# bgImage Image.open(./image/bg.png)# bgImage.im.mode RGBAbgBytes bgImage.load()x 0while x bgImage.size[0]:y 0# 点》》线灰度线条数量verticalLineCount 0while y bgImage.size[1]:px bgBytes[x, y]r px[0]g px[1]b px[2]# alph px[3]# print(px)if self.isDarkStyle(r, g, b) and self.isGrayPx(r, g, b) and self.isOpaque(px):verticalLineCount 1else:verticalLineCount 0y 1continueif verticalLineCount self.config[minVerticalLineCount]:# 连续多个像素都是灰度像素直线# print(x, y)return xy 1x 1passif __name__ __main__:bgImage Image.open(./image/bg.png)veriImageUtil VeriImageUtil()# veriImageUtil.updateConfig({# grayOffset: 20,# opaque: 0.6,# minVerticalLineCount: 10# })bgOffsetX veriImageUtil.getVerticalLineOffsetX(bgImage)print(bgOffsetX:{} .format(bgOffsetX)) 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 使用selenium进行滑动验证会失败 首先我们需要从html中获取滑块验证的图片通过执行js将画布像素转为base64然后python即可获取进行拖拽处理 from selenium import webdriver import time import base64 from PIL import Image from io import BytesIO from selenium.webdriver.support.ui import WebDriverWaitdef checkVeriImage(driver): WebDriverWait(driver, 5).until(lambda driver: driver.find_element_by_css_selector(.geetest_canvas_bg.geetest_absolute))time.sleep(1)im_info driver.execute_script(return document.getElementsByClassName(geetest_canvas_bg geetest_absolute)[0].toDataURL(image/png);)# 拿到base64编码的图片信息im_base64 im_info.split(,)[1]# 转为bytes类型im_bytes base64.b64decode(im_base64)with open(./temp_bg.png, wb) as f:# 保存图片到本地方便查看预览f.write(im_bytes)image_data BytesIO(im_bytes)bgImage Image.open(image_data)# 滑块距离左边有 5~10 像素左右误差offsetX VeriImageUtil().getVerticalLineOffsetX(bgImage)eleDrag driver.find_element_by_css_selector(.geetest_slider_button)action_chains webdriver.ActionChains(driver)action_chains.drag_and_drop_by_offset(eleDrag,offsetX-10,0).perform()1234567891011121314151617181920212223242526272829 貌似可以了但实际上验证时会遇到“拼图被怪物吃掉了请重试”导致失败。这是因为被检测到机器人爬虫操作了。 避开人机识别 | B站滑块验证码的人机识别其实不咋滴主要靠是否存在停留间隔来判断。一开始被网上文章误导弄了什么距离初速度乘以时间t 1/2加速度乘以(时间平方)模拟拖拽实际上是完全不对路的。 webdriver.ActionChains(driver).drag_and_drop_by_offset(eleDrag,offsetX-10,0).perform() 拖动滑块会导致验证失败。在B站中这是因为这个动作太快了的缘故。 有的同学就打算直接加 time.sleep(1) 了这么做是不会成功的会提示拼图被怪物吃掉了请重试 实际上人做滑块验证的过程可以归为手指快速拖拽验证码到指定位置修正误差停留一会儿释放滑块。 简单实现 代码可以简单实现都不需要模拟人修正拖拽误差的过程普通网站不会去统计这个至少B站不会。 def simpleSimulateDragX(self, source, targetOffsetX):简单拖拽模仿人的拖拽快速沿着X轴拖动直接一步到达正确位置再暂停一会儿然后释放拖拽动作B站是依据是否有暂停时间来分辨人机的这个方法适用。:param source: :param targetOffsetX: :return: None#参考drag_and_drop_by_offset(eleDrag,offsetX-10,0)的实现使用move方法action_chains webdriver.ActionChains(self.driver)# 点击准备拖拽action_chains.click_and_hold(source)action_chains.pause(0.2)action_chains.move_by_offset(targetOffsetX,0)action_chains.pause(0.6)action_chains.release()action_chains.perform() 12345678910111213141516171819 添加修正过程的实现 其实也就最后一段多出了fix的过程 action_chains.move_by_offset(10,0) def fixedSimulateDragX(self, source, targetOffsetX):#参考drag_and_drop_by_offset(eleDrag,offsetX-10,0)的实现使用move方法action_chains webdriver.ActionChains(self.driver)# 点击准备拖拽action_chains.click_and_hold(source)action_chains.pause(0.2)action_chains.move_by_offset(targetOffsetX-10,0)action_chains.pause(0.6)action_chains.move_by_offset(10,0)action_chains.pause(0.6)action_chains.release()action_chains.perform() 12345678910111213 终极版实现 | 为了更像人类操作可以进行拖拽间隔时间和拖拽次数、距离的随机化。虽然这对B站没什么用还可能会导致验证时间变久一些。 拖拽多次可以使用循环遍历不过代码可能不好理解直接判断就行最多也就两到3次就完成修正误差的过程。 def __getRadomPauseScondes(self)::return:随机的拖动暂停时间return random.uniform(0.6, 0.9)def simulateDragX(self, source, targetOffsetX):模仿人的拖拽动作快速沿着X轴拖动存在误差再暂停然后修正误差防止被检测为机器人出现“图片被怪物吃掉了”等验证失败的情况:param source:要拖拽的html元素:param targetOffsetX: 拖拽目标x轴距离:return: Noneaction_chains webdriver.ActionChains(self.driver)# 点击准备拖拽action_chains.click_and_hold(source)# 拖动次数二到三次dragCount random.randint(2, 3)if dragCount 2:# 总误差值sumOffsetx random.randint(-15, 15)action_chains.move_by_offset(targetOffsetX sumOffsetx, 0)# 暂停一会action_chains.pause(self.__getRadomPauseScondes())# 修正误差防止被检测为机器人出现图片被怪物吃掉了等验证失败的情况action_chains.move_by_offset(-sumOffsetx, 0)elif dragCount 3:# 总误差值sumOffsetx random.randint(-15, 15)action_chains.move_by_offset(targetOffsetX sumOffsetx, 0)# 暂停一会action_chains.pause(self.__getRadomPauseScondes())# 已修正误差的和fixedOffsetX 0# 第一次修正误差if sumOffsetx 0:offsetx random.randint(sumOffsetx, 0)else:offsetx random.randint(0, sumOffsetx)fixedOffsetX fixedOffsetX offsetxaction_chains.move_by_offset(-offsetx, 0)action_chains.pause(self.__getRadomPauseScondes())# 最后一次修正误差action_chains.move_by_offset(-sumOffsetx fixedOffsetX, 0)action_chains.pause(self.__getRadomPauseScondes())else:raise Exception(莫不是系统出现了问题!)# 参考action_chains.drag_and_drop_by_offset()action_chains.release()action_chains.perform() 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 终章完整代码 | 示例代码和效果图。完整示例代码本身只是示例方便测试用的不进行成功验证等处理验证成功后python会直接异常退出。 本文完整示例代码如下 # -*- coding: utf-8 -*- # Date:2020/2/15 2:09 # Author: Lu # Description bilibili滑块验证码识别。B站有反爬限制过快地拖拽会提示“怪物吃了拼图请重试”。 # 目前B站有三张图片只要对比完整图和缺失滑块背景图的像素就可以得到偏移图片y轴距离减去滑块空白距离需要滑动的像素距离 # 这里采用边缘检测检测缺失滑块的底图是否存在一条灰色竖线即认为是滑块目标位置存在失败的概率适用范围应该更大些。from selenium import webdriver import time import base64 from PIL import Image from io import BytesIO from selenium.webdriver.support.ui import WebDriverWait import random import copyclass VeriImageUtil():def __init__(self):self.defaultConfig {grayOffset: 20,opaque: 1,minVerticalLineCount: 30}self.config copy.deepcopy(self.defaultConfig)def updateConfig(self, config):# temp copy.deepcopy(config)for k in self.config:if k in config.keys():self.config[k] config[k]def getMaxOffset(self, *args):# 计算偏移平均值最大的数av sum(args) / len(args)maxOffset 0for a in args:offset abs(av - a)if offset maxOffset:maxOffset offsetreturn maxOffsetdef isGrayPx(self, r, g, b):# 是否是灰度像素点允许波动offsetreturn self.getMaxOffset(r, g, b) self.config[grayOffset]def isDarkStyle(self, r, g, b):# 灰暗风格return r 128 and g 128 and b 128def isOpaque(self, px):# 不透明return px[3] 255 * self.config[opaque]def getVerticalLineOffsetX(self, bgImage):# bgImage Image.open(./image/bg.png)# bgImage.im.mode RGBAbgBytes bgImage.load()x 0while x bgImage.size[0]:y 0# 点》》线灰度线条数量verticalLineCount 0while y bgImage.size[1]:px bgBytes[x, y]r px[0]g px[1]b px[2]# alph px[3]# print(px)if self.isDarkStyle(r, g, b) and self.isGrayPx(r, g, b) and self.isOpaque(px):verticalLineCount 1else:verticalLineCount 0y 1continueif verticalLineCount self.config[minVerticalLineCount]:# 连续多个像素都是灰度像素直线认为需要滑动这么多# print(x, y)return xy 1x 1passclass DragUtil():def __init__(self, driver):self.driver driverdef __getRadomPauseScondes(self)::return:随机的拖动暂停时间return random.uniform(0.6, 0.9)def simulateDragX(self, source, targetOffsetX):模仿人的拖拽动作快速沿着X轴拖动存在误差再暂停然后修正误差防止被检测为机器人出现“图片被怪物吃掉了”等验证失败的情况:param source:要拖拽的html元素:param targetOffsetX: 拖拽目标x轴距离:return: Noneaction_chains webdriver.ActionChains(self.driver)# 点击准备拖拽action_chains.click_and_hold(source)# 拖动次数二到三次dragCount random.randint(2, 3)if dragCount 2:# 总误差值sumOffsetx random.randint(-15, 15)action_chains.move_by_offset(targetOffsetX sumOffsetx, 0)# 暂停一会action_chains.pause(self.__getRadomPauseScondes())# 修正误差防止被检测为机器人出现图片被怪物吃掉了等验证失败的情况action_chains.move_by_offset(-sumOffsetx, 0)elif dragCount 3:# 总误差值sumOffsetx random.randint(-15, 15)action_chains.move_by_offset(targetOffsetX sumOffsetx, 0)# 暂停一会action_chains.pause(self.__getRadomPauseScondes())# 已修正误差的和fixedOffsetX 0# 第一次修正误差if sumOffsetx 0:offsetx random.randint(sumOffsetx, 0)else:offsetx random.randint(0, sumOffsetx)fixedOffsetX fixedOffsetX offsetxaction_chains.move_by_offset(-offsetx, 0)action_chains.pause(self.__getRadomPauseScondes())# 最后一次修正误差action_chains.move_by_offset(-sumOffsetx fixedOffsetX, 0)action_chains.pause(self.__getRadomPauseScondes())else:raise Exception(莫不是系统出现了问题!)# 参考action_chains.drag_and_drop_by_offset()action_chains.release()action_chains.perform()def simpleSimulateDragX(self, source, targetOffsetX):简单拖拽模仿人的拖拽快速沿着X轴拖动直接一步到达正确位置再暂停一会儿然后释放拖拽动作B站是依据是否有暂停时间来分辨人机的这个方法适用。:param source: :param targetOffsetX: :return: Noneaction_chains webdriver.ActionChains(self.driver)# 点击准备拖拽action_chains.click_and_hold(source)action_chains.pause(0.2)action_chains.move_by_offset(targetOffsetX, 0)action_chains.pause(0.6)action_chains.release()action_chains.perform()def checkVeriImage(driver):WebDriverWait(driver, 5).until(lambda driver: driver.find_element_by_css_selector(.geetest_canvas_bg.geetest_absolute))time.sleep(1)im_info driver.execute_script(return document.getElementsByClassName(geetest_canvas_bg geetest_absolute)[0].toDataURL(image/png);)# 拿到base64编码的图片信息im_base64 im_info.split(,)[1]# 转为bytes类型im_bytes base64.b64decode(im_base64)with open(./temp_bg.png, wb) as f:# 保存图片到本地f.write(im_bytes)image_data BytesIO(im_bytes)bgImage Image.open(image_data)# 滑块距离左边有 5 像素左右误差offsetX VeriImageUtil().getVerticalLineOffsetX(bgImage)print(offsetX: {}.format(offsetX))if not type(offsetX) int:# 计算不出重新加载driver.find_element_by_css_selector(.geetest_refresh_1).click()checkVeriImage(driver)returnelif offsetX 0:# 计算不出重新加载driver.find_element_by_css_selector(.geetest_refresh_1).click()checkVeriImage(driver)returnelse:dragVeriImage(driver, offsetX)def dragVeriImage(driver, offsetX):# 可能产生检测到右边缘的情况# 拖拽eleDrag driver.find_element_by_css_selector(.geetest_slider_button)dragUtil DragUtil(driver)dragUtil.simulateDragX(eleDrag, offsetX - 10)time.sleep(2.5)if isNeedCheckVeriImage(driver):checkVeriImage(driver)returndragUtil.simulateDragX(eleDrag, offsetX - 6)time.sleep(2.5)if isNeedCheckVeriImage(driver):checkVeriImage(driver)return# 滑块宽度40左右dragUtil.simulateDragX(eleDrag, offsetX - 56)time.sleep(2.5)if isNeedCheckVeriImage(driver):checkVeriImage(driver)returndragUtil.simulateDragX(eleDrag, offsetX - 52)if isNeedCheckVeriImage(driver):checkVeriImage(driver)returndef isNeedCheckVeriImage(driver):if driver.find_element_by_css_selector(.geetest_panel_error).is_displayed():driver.find_element_by_css_selector(.geetest_panel_error_content).click();return Truereturn Falsedef task():# 此步骤很重要设置chrome为开发者模式防止被各大网站识别出来使用了Selenium# options webdriver.ChromeOptions()# options.add_experimental_option(excludeSwitches, [enable-automation])options webdriver.FirefoxOptions()# driver webdriver.Firefox(executable_pathr../../../res/webdriver/geckodriver_x64_0.26.0.exe,optionsoptions)driver webdriver.Firefox(executable_pathr../../../res/webdriver/geckodriver_x64_0.26.0.exe,optionsoptions)driver.get(https://passport.bilibili.com/login)time.sleep(3)driver.find_element_by_css_selector(#login-username).send_keys(1234567)driver.find_element_by_css_selector(#login-passwd).send_keys(abcdefg)driver.find_element_by_css_selector(.btn.btn-login).click()time.sleep(2)checkVeriImage(driver)pass# 该方法用来确认元素是否存在如果存在返回flagtrue否则返回false def isElementExist(driver, css):try:driver.find_element_by_css_selector(css)return Trueexcept:return Falseif __name__ __main__:task()
http://www.pierceye.com/news/943431/

相关文章:

  • 装饰网站建设软件下载公司旅游视频网站模板免费下载
  • aws网站建设个体户做网站去哪里做
  • 用四字成语做网站域名好吗宁波网站推广专业服务
  • 深圳网站建设公司是网络推广网上营销
  • 网站视频站建设教程和仿qq商城版淘宝客网站源码模板+带程序后台文章dede织梦企业程序
  • 温州红酒网站建设长沙移动网站建设
  • 如何制作网站?企业网站制作步骤
  • 桓台县旅游网站建设购物网站建设技术难点
  • 单页网站推广网站qq链接怎么做
  • wordpress仿站步骤平乡网站建设
  • 青岛高端网站建设公司新网站seo技术
  • 手机网站后台甘肃网络推广技巧
  • 做co网站阿里云建站方案
  • 如何做网站首页优化怎么查网站点击量
  • 北京网站制作百度推广潜江资讯网二手房出售
  • 北京建网站软件深圳企业网站
  • 网站关键词互点备案网站简介怎么写
  • 网站建设报告书范文哈尔滨网站公司哪家好
  • 景观毕业设计作品网站公司网站销售平台建设费分录
  • 品牌网站建设还来大蝌蚪华为手机WordPress
  • 东莞制作企业网站公司网站营销活动页面制作
  • 有中文网站 怎么做英文网站企业网站建设 价格
  • 网络游戏网站开发建设工程施工合同样本
  • 陕西网站制作公司泸州中泸集团建设有限公司网站
  • 营销型网站建设的概念电子商务公司最低注册资本
  • 计划书网站推广的目录怎么做太原便宜做网站的公司哪家好
  • wordpress 直播插件麒麟seo外推软件
  • 网站检测报告哪里做寰宇seo
  • 徐州微信网站建设网站建设员课程
  • 做现货需要关注的网站wordpress+游戏网站