selenium模拟登录QQ邮箱


写在前面

本来想利用自动化测试实现跳过猫眼验证中心,自动拖动滑块验证的功能是实现了,但猫眼还有别的检测方法来判断用户行为,所以这条路没有走通,在这里记录下QQ邮箱的自动登录。

用到的包

#用于sleep
import time
#selenium自动化框架
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains

配置options

#后面两行可以无界面驱动chrome
chrome_options = Options()
#chrome_options.add_argument('--headless')
#chrome_options.add_argument('--disable-gpu')

主函数

简单说一下如何找模块对应的id,在网页按f12审查元素,鼠标找到目标模块,右键,检查。 如果网页中能找到id但browser定位不到,可以看看是不是没有切换iframe。 请参阅selenium定位之iframe

def test():
    #n你可以在config文件里写自己的账号密码,不需要的话删掉即可
    import config
    #获取账号密码
    mailuser = config.mailusername
    mailpsw = config.mailpassword
    #创建browser对象,实质上用于驱动chrome
    browser = webdriver.Chrome(executable_path = 'chromedriver.exe',options = chrome_options)
    #访问目标地址
    browser.get('http://mail.qq.com/')
    #窗口最大化
    #browser.maximize_window()
    #切换到对应的iframe
    #login_frame = browser.find_element_by_id('login_frame')
    #与上一行同理,选择喜欢的方式即可
    browser.switch_to.frame('login_frame')
    #根据id找到账号输入框
    username = browser.find_element_by_id('u')
    #清空输入框
    username.clear()
    #输入账号
    username.send_keys(mailuser)
    #根据id找到密码输入框,清空后输入密码
    password = browser.find_element_by_xpath('//*[@id="p"]')
    password.clear()
    password.send_keys(mailpsw)

    #根据id找到登录按钮
    loginButton = browser.find_element_by_id('login_button')
    #定义一个存储browser事件的对象
    ac1 = ActionChains(browser)
    #事件为点击loginbutton按钮,并实施该事件,如果不perform,则暂不执行
    ac1.click(loginButton).perform()
    #休眠3秒,不然无法正确获取滑块验证模块
    time.sleep(3)
    #如果出现滑块验证,则切换到对应的iframe,登录成功的话则不做任何事情
    try:
        verify = browser.find_element_by_id('tcaptcha_iframe')
        browser.switch_to.frame(verify)
    except:
        pass
    #滑块要右移的距离
    axis = 165
    #执行滑块验证
    while True:
        #这里用出现异常来跳出循环
        try:
            #当验证通过,则无法找到滑块对应的id,此时将跳出循环
            dragElement = browser.find_element_by_id('tcaptcha_drag_button')
            #定义browser事件
            ac2 = ActionChains(browser)
            #根据距离移动滑块axis为x轴,0为y轴
            ac2.drag_and_drop_by_offset(dragElement,axis,0).perform()
            #休眠两秒
            time.sleep(2)
            #验证失败则距离加5,三次以后验证码会更新,此时将axis还原
            axis += 5
            if axis > 180:
                axis = 165
        except:
            break
    #休眠五秒
    time.sleep(5)
    #退出浏览器
    browser.quit()

两个技巧

selenium测试时会出现命令行窗口,不过我们有办法隐藏它:

修改源码Lib\site-packages\selenium\webdriver\common\ _services.py
找到start()添加配置参数 creationflags=134217728 即可

部分网站会检测浏览器的window.navigator.webdriver,此项在正常浏览器中值为undefined,在chromedriver中为true,成为了selenium可识别的指纹,不过仍有办法将其擦除:

#为你的webdriver对象(t替换browser)添加如下代码
#此改动在webdriver对象关闭前一直有效
browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
              "source": """
                Object.defineProperty(navigator, 'webdriver', {
                  get: () => undefined
                })
              """
            })