开头语:
除非是很简单的参数能够解决滑块问题或者追求效率的业务,否则的话,我还是会selenium来解决,并且接下来的验证码模式的话不需要使用到原图进行比较!!我发现很多网站都是基于比较原图,发现缺口的方式来获取坐标,而我有不同的小思路。并且该滑块验证码有特殊性,如果遇到可以收藏并点赞!!!!
Python版本:3
selenium模块、PIL模块 以及一些python自带的模块。
有插件的就不用管他了,如果没有就找小编领取一下!在文章下方有源码和驱动下载的!
安装python并添加到环境变量,pip安装需要的相关模块即可。
接着,我们用它来自动访问一下自己站的登录界面:
browser.get("https://ad.oceanengine.com/pages/login/index.html")
设置一下等待时间,并自动填充一下用户名和密码:
wait = WebDriverWait(browser, 30)
element = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="login"]/section/div[3]/div[10]/div'))) # 它的作用现在就是,等!!!!!!!
input_user = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="login"]/section/div[3]/div[4]/input'))).send_keys('user') # 输入账号
input_password = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="login"]/section/div[3]/div[5]/input[1]'))).send_keys('password') # 输入密码
element.click()#点击登录time.sleep(3)#等待三秒钟就会有验证码了
其中用户名和密码的输入框都直接用xpath来定位,非常方便
不会还有人不知道吧,不会吧不会吧~
上面的操作一完成,就有验证码弹出来了,直接就有缺口,没有原图,无法做比较
验证码如图
验证码出来的操作
getimage = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="validate-big"]'))) # 等出图片
browser.get_screenshot_as_file("./全屏截图.jpg")
imgelement = browser.find_element_by_xpath('//*[@id="verify-bar-box"]/div[2]/img[2]') # 定位验证码
rangle = (324,350, 590,500) # 写成我们需要截取的位置坐标
i = Image.open("./全屏截图.jpg") # 打开截图
i = i.convert('RGB')
frame1 = i.crop(rangle)# frame1.show()# frame1.save('./验证码截图.jpg')
data = frame1.getdata()#获取rgb
w, h = frame1.size#获取宽高XCoordinates = 0
接下来是核心算法,求出需要移动的x坐标距离
for x in range(1, w - 1):
for y in range(1, h - 1):
mid_pixel = data[w * y + x] # 中央像素点像素值 if mid_pixel[0] > 230 and mid_pixel[1] > 230 and mid_pixel[2] > 230 and int(x) > 100: # 找出上下左右四个方向像素点像素值
top_pixel = data[w * (y - 1) + x] # 上
down_pixel = data[w * (y + 1) + x] # 下
if top_pixel[0] > 230 and top_pixel[1] > 230 and top_pixel[2] > 230 and down_pixel[0]> 230 and down_pixel[1]> 230 and down_pixel[2]> 230:
XCoordinates=x
这是拖动操作!!包含了拖动时轨迹的变速运动!!
element = browser.find_element_by_xpath('//*[@id="validate-drag-wrApper"]/div[2]/img')
location = element.location# # 获得滑动圆球的高度y = location["y"]
# # 鼠标点击元素并按住不放# print("第一步,点击元素")
ActionChains(browser).click_and_hold(on_element=element).perform()## ActionChains(browser).move_by_offset(xoffset=0, yoffset=y - 445).perform()
## time.sleep(0.15)
# print("第二步,拖动元素")
distance=XCoordinates-60
# 初速度v = 0
# 单位时间为0.2s来统计轨迹,轨迹即0.2内的位移,越低看起来越丝滑!!
t = 0.08
# 位移/轨迹列表,列表内的一个元素代表0.2s的位移
tracks = []# 当前的位移current = 0
# 到达mid值开始减速mid = distance * 5 / 8
distance += 10 # 先滑过一点,最后再反着滑动回来
# a = random.randint(1,3)
while current < distance:
if current < mid:
# 加速度越小,单位时间的位移越小,模拟的轨迹就越多越详细 a = random.randint(100, 200) # 加速运动
else:
a = -random.randint(2, 10) # 减速运动
# 初速度 v0 = v # 0.2秒时间内的位移
s = v0 * t + 0.5 * a * (t ** 2)
# 当前的位置 current += s # 添加到轨迹列表 tracks.append(round(s)) # 速度已经达到v,该速度作为下次的初速度 v = v0 + a * t if current>distance:
break
# 反着滑动到大概准确位置# for i in range(4):
# tracks.append(-random.randint(1, 3))
# for i in range(4):
# tracks.append(-random.randint(1,3))
random.shuffle(tracks)
count=0
for item in tracks:
print(item)
count+=item ActionChains(browser).move_by_offset(xoffset=item, yoffset=random.randint(-2, 2)).perform()
# ActionChains(browser).move_to_element_with_offset(to_element=element, xoffset=XCoordinates-18,yoffset=y - 445).perform()
# time.sleep(2)
# # 释放鼠标print(count)
ActionChains(browser).release(on_element=element).perform()
然后就能登陆了!!!完美!!!其实还有登陆后的操作,也一并奉上吧~点击操作呢
jiazaichenggong = wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[25]/div/div/div[2]/div[2]/button')))
jiazaichenggong.click() Exitboot = wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/div[2]/div/div[6]/div/div[4]/div')))#点击推出引导
Exitboot.click() closekey=wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[13]/div[2]/div[3]/button')))#查看快捷键
closekey.click() time.sleep(3)
# closekey.send_keys(Keys.ESCAPE) ActionChains(browser).move_by_offset(300,238).click().perform()
time.sleep(5)
clickdate=wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/div[1]/div[3]/div[2]/div/div[1]/div')))#点击时间
clickdate.click() print('请输入时间选择-格式如下2020.09.01')
stime=input('请输入开始时间:')
etime = input('请输入结束时间:')
time.sleep(10)
clickstime = wait.until(EC.presence_of_element_located((By.XPATH, f"//td[@title='{stime}']"))) # 点击时间
clickstime.click() clicketime = wait.until(EC.presence_of_element_located((By.XPATH, f"//td[@title='{etime}']"))) # 点击时间
clicketime.click() time.sleep(60)