知乎模拟登入
声明:本文只作学习研究,禁止用于非法用途,否则后果自负,如有侵权,请告知删除,谢谢!
项目场景:
这次给大家带来的是知乎的selenium自动登入,使用的是qq授权的登入入口,链接在此,之前有尝试使用登入的API接口进行模拟登入,但是没有成功 ~,所以还是老老实实先用浏览器登入吧。
解决方案:
1.OK,现在开始尝试吧,点击qq授权图标,再点击账号密码登入,输入qq账号密码后,就会跳出补缺口的滑块类型验证码.
2.乍一看补缺块的验证码很头痛,这个网站还好,并没有生物行为特征的检测,只要计算出滑块需要滑动的距离即可。具体验证思路如下:
先获取两张图片,一张是有缺口的完整图,一张是缺块图。
然后进行二值化处理。
接着使用cv2.matchTemplate去匹配滑块所在缺口图的位置,返回距离x,再去浏览器上获取实际滑动的距离distance。
这个时候拿到的x并不是selenium去模拟滑动的距离,需要多测几组(x,distance),然后再用曲线拟合工具,来计算出实际需要滑动距离的公式。
最后获取的距离才是selenium实际滑动的距离。
3.先说两张图片的获取方法,两个图片地址OK。
4.计算缺块位置。
def get_diff_location(): # 获取图片并灰度化 block = cv2.imread("block.jpg", 0) # 缺块图片 index = cv2.imread("index.jpg", 0) # 背景图片 # 二值化后的图片名称 block1 = "block1.jpg" index1 = "index1.jpg" # 将二值化后的图片进行保存 cv2.imwrite(block1, block) cv2.imwrite(index1, index) block = cv2.imread(block1) block = cv2.cvtColor(block, cv2.COLOR_RGB2GRAY) block = abs(255 - block) cv2.imwrite(block1, block) block = cv2.imread(block1) template = cv2.imread(index1) # 获取偏移量 result = cv2.matchTemplate(block, template, cv2.TM_CCOEFF_NORMED) # 查找block在template中的位置,返回result是一个矩阵,是每个点的匹配结果 x, y = np.unravel_index(result.argmax(), result.shape) # print("x方向的偏移", int(y * 0.4 + 18), 'x:', x, 'y:', y) return y 复制代码
5.获取实际滑动距离,两个值减一下。
6.然后4,5步骤多取几组数据放到曲线拟合的网站来输出换算的公式,最后我们用selenium测试一下,一般1-3次就会成功!
7.最后贴下完整的代码!
import cv2 import numpy as np import time import requests from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.common.desired_capabilities import DesiredCapabilities def get_diff_location(): # 获取图片并灰度化 block = cv2.imread("block.jpg", 0) # 缺块图片 index = cv2.imread("index.jpg", 0) # 背景图片 # 二值化后的图片名称 block1 = "block1.jpg" index1 = "index1.jpg" # 将二值化后的图片进行保存 cv2.imwrite(block1, block) cv2.imwrite(index1, index) block = cv2.imread(block1) block = cv2.cvtColor(block, cv2.COLOR_RGB2GRAY) block = abs(255 - block) cv2.imwrite(block1, block) block = cv2.imread(block1) template = cv2.imread(index1) # 获取偏移量 result = cv2.matchTemplate(block, template, cv2.TM_CCOEFF_NORMED) # 查找block在template中的位置,返回result是一个矩阵,是每个点的匹配结果 x, y = np.unravel_index(result.argmax(), result.shape) # print("x方向的偏移", int(y * 0.4 + 18), 'x:', x, 'y:', y) return y def run(): url = 'https://www.zhihu.com/signin?next=%2F' option = webdriver.ChromeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) # webdriver防检测 option.add_argument("--no-sandbox") option.add_argument("--disable-dev-usage") desired_capabilities = DesiredCapabilities.CHROME # 修改页面加载策略 desired_capabilities["pageLoadStrategy"] = "none" # 注释这两行会导致最后输出结果的延迟,即等待页面加载完成再输出 driver = webdriver.Chrome(options=option) driver.get(url) time.sleep(2) driver.find_element_by_xpath('//*[@id="root"]/div/main/div/div/div/div[3]/span[2]/button[2]').click() # 点击qq授权登入 time.sleep(2) driver.switch_to.window(driver.window_handles[-1]) # 切换句柄 time.sleep(1) driver.switch_to.frame("ptlogin_iframe") driver.find_element_by_id('switcher_plogin').click() # 点击密码登入 time.sleep(2) #输入账号密码 driver.find_element_by_id('u').send_keys('123123123') driver.find_element_by_id('p').send_keys('123123123') time.sleep(1) # 点击登入 driver.find_element_by_id('login_button').click() time.sleep(3) driver.switch_to.frame('tcaptcha_iframe') while True: # 保存带缺块的背景图 with open('index.jpg','wb') as f: url = driver.find_element_by_id('slideBg').get_attribute('src') f.write(requests.get(url).content) # 保存缺块图 with open('block.jpg','wb') as f: url = driver.find_element_by_id('slideBlock').get_attribute('src') f.write(requests.get(url).content) #获取滑块 button = driver.find_element_by_id('tcaptcha_drag_thumb') # 滑动滑块 ActionChains(driver).click_and_hold(button).perform() x = get_diff_location() print('拟合前的距离',x) if x > 500: # 刷新验证码 print('拟合前的距离有误') ActionChains(driver).release().perform() # 释放鼠标 driver.find_element_by_id('e_reload').click() time.sleep(2) continue distance = int(-0.002886710239855681*x*x*x+4.044880174577657*x*x-1888.1544118978823*x+293800.78433441074) if (distance > 200) and (distance < 300): distance -= 100 elif distance > 300: print('距离出错') # 刷新验证码 ActionChains(driver).release().perform() # 释放鼠标 driver.find_element_by_id('e_reload').click() time.sleep(2) continue print('需要滑动的大概距离',distance) ActionChains(driver).move_by_offset(xoffset=distance, yoffset=0).perform() time.sleep(1) ActionChains(driver).release().perform() # 释放鼠标 time.sleep(2) # 检测是否滑动成功 try: driver.find_element_by_id('tcaptcha_drag_thumb') print('滑动失败,即将再次尝试!') # 刷新验证码 driver.find_element_by_id('e_reload').click() time.sleep(2) except Exception: break print('验证成功!') time.sleep(11111) if __name__ == '__main__': run()
作者:逆向阿J
链接:https://juejin.cn/post/7023553499736571940