赞
踩
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 = 0
for a in args:
offset = abs(av - a)
if offset > maxOffset:
maxOffset = offset
return maxOffset
def isGrayPx(self, r, g, b):
return self.getMaxOffset(r, g, b) < self.config[“grayOffset”]
def isDarkStyle(self, r, g, b):
return r < 128 and g < 128 and b < 128
def isOpaque(self, px):
return px[3] >= 255 * self.config[“opaque”]
def getVerticalLineOffsetX(self, bgImage):
bgBytes = bgImage.load()
x = 0
while x < bgImage.size[0]:
y = 0
verticalLineCount = 0
while y < bgImage.size[1]:
px = bgBytes[x, y]
r = px[0]
g = px[1]
b = px[2]
if self.isDarkStyle(r, g, b) and self.isGrayPx(r, g, b) and self.isOpaque(px):
verticalLineCount += 1
else:
verticalLineCount = 0
y += 1
continue
if verticalLineCount >= self.config[“minVerticalLineCount”]:
return x
y += 1
x += 1
pass
if name == ‘main’:
bgImage = Image.open(“./image/bg.png”)
veriImageUtil = VeriImageUtil()
bgOffsetX = veriImageUtil.getVerticalLineOffsetX(bgImage)
print("bgOffsetX:{} ".format(bgOffsetX))
使用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 WebDriverWait
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”);’)
im_base64 = im_info.split(‘,’)[1]
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)
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()
貌似可以了,但实际上,验证时会遇到“拼图被怪物吃掉了,请重试”,导致失败。这是因为被检测到机器人(爬虫)操作了。
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()
其实也就最后一段多出了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()
为了更像人类操作,可以进行拖拽间隔时间和拖拽次数、距离的随机化。虽然这对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: None
“”"
action_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 + offsetx
action_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.release()
action_chains.perform()
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 copy
class VeriImageUtil():
def init(self):
self.defaultConfig = {
“grayOffset”: 20,
“opaque”: 1,
“minVerticalLineCount”: 30
}
self.config = copy.deepcopy(self.defaultConfig)
def updateConfig(self, 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 = 0
for a in args:
offset = abs(av - a)
if offset > maxOffset:
maxOffset = offset
return maxOffset
def isGrayPx(self, r, g, b):
return self.getMaxOffset(r, g, b) < self.config[“grayOffset”]
def isDarkStyle(self, r, g, b):
return r < 128 and g < 128 and b < 128
def isOpaque(self, px):
return px[3] >= 255 * self.config[“opaque”]
def getVerticalLineOffsetX(self, bgImage):
bgBytes = bgImage.load()
x = 0
while x < bgImage.size[0]:
y = 0
verticalLineCount = 0
while y < bgImage.size[1]:
px = bgBytes[x, y]
r = px[0]
g = px[1]
b = px[2]
if self.isDarkStyle(r, g, b) and self.isGrayPx(r, g, b) and self.isOpaque(px):
verticalLineCount += 1
else:
verticalLineCount = 0
y += 1
continue
if verticalLineCount >= self.config[“minVerticalLineCount”]:
return x
y += 1
x += 1
pass
class DragUtil():
def init(self, driver):
self.driver = driver
def __getRadomPauseScondes(self):
“”"
:return:随机的拖动暂停时间
“”"
return random.uniform(0.6, 0.9)
def simulateDragX(self, source, targetOffsetX):
“”"
模仿人的拖拽动作:快速沿着X轴拖动(存在误差),再暂停,然后修正误差
防止被检测为机器人,出现“图片被怪物吃掉了”等验证失败的情况
:param source:要拖拽的html元素
:param targetOffsetX: 拖拽目标x轴距离
:return: None
“”"
action_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 + offsetx
action_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.release()
action_chains.perform()
def simpleSimulateDragX(self, source, targetOffsetX):
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)
到现在。**
深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-q0aM0nBe-1712537749773)]
[外链图片转存中…(img-LFHCnOlQ-1712537749774)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。