[2020-09-24] 知乎模拟登入--selenium

声明:本文只作学习研究,禁止用于非法用途,否则后果自负,如有侵权,请告知删除,谢谢!

项目场景:

这次给大家带来的是知乎的selenium自动登入,使用的是qq授权的登入入口,链接在此,之前有尝试使用登入的API接口进行模拟登入,但是没有成功 ~,所以还是老老实实先用浏览器登入吧。

在这里插入图片描述


解决方案:


1.OK,现在开始尝试吧,点击qq授权图标,再点击账号密码登入,输入qq账号密码后,就会跳出补缺口的滑块类型验证码.

在这里插入图片描述

2.乍一看补缺块的验证码很头痛,这个网站还好,并没有生物行为特征的检测,只要计算出滑块需要滑动的距离即可。具体验证思路如下:
  1. 先获取两张图片,一张是有缺口的完整图,一张是缺块图。
  2. 然后进行二值化处理。
  3. 接着使用cv2.matchTemplate去匹配滑块所在缺口图的位置,返回距离x,再去浏览器上获取实际滑动的距离distance。
  4. 这个时候拿到的x并不是selenium去模拟滑动的距离,需要多测几组(x,distance),然后再用曲线拟合工具,来计算出实际需要滑动距离的公式。
  5. 最后获取的距离才是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()


猜你喜欢

转载自blog.csdn.net/qq_26079939/article/details/108777370