微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python +硒-Microsoft 2FA

如何解决Python +硒-Microsoft 2FA

我正在尝试使用Python和Selenium登录到Azure DevOps。我可以很好地输入用户名和密码,但是我在手机上设置了Microsoft Authenticator App,以便在尝试登录提示我“批准”或“拒绝”。

我尝试让Selenium等到登录页面上的“否”按钮元素出现(请参见下面的屏幕截图),

enter image description here

但它似乎不喜欢它。我看了this post,它与Google的Authenticator有关。该解决方案使用了Google Authenticator的秘密以及pyotp。我似乎无法找到一种方法,至少对我本人而言,可以从MS Authenticator中获得秘密。我已签出this指南,但无权访问Azure AD。

这是我尝试在2FA之后等待屏幕显示代码

def signin(user,passwd):
    # find elements before passing information
    username = browser.find_element_by_name('loginfmt')
    username.send_keys(user)
    username.send_keys(Keys.ENTER)

    time.sleep(1)

    password = browser.find_element_by_name('passwd')
    password.send_keys(passwd)
    password.send_keys(Keys.ENTER)

    try:
        webdriverwait(browser,60).until(
            EC.element_to_be_clickable((By.ID,"idBtn_Back"))
        ).click()
    finally:
        sys.exit('Timeout for 2FA approval reached. Try again.')

不幸的是,正如我在上面简要提到的那样,即使在保持登录状态页面出现后,Python也无法检测到“否”按钮。我真的不在乎使用哪个按钮,因为脚本使用的是我未登录的浏览器的单独实例。

我已经考虑设置一个time.sleep()命令,但这似乎是一种非常愚蠢的方法。有人有建议吗?

解决方法

Python无法检测到“否”按钮。

每当我发现Python发生奇怪的事情,绝对没有任何意义,程序根本不执行所告诉的事情时,请相信我,我总是在那里找到try-except语句。而我的朋友是你的错。

finally will always executetry是否有效都没关系。

WebDriverWait(browser,60).until(
            EC.element_to_be_clickable((By.ID,"idBtn_Back"))
        ).click()

完全是错误的!尝试单独运行它:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-13-b43596b524d7> in <module>
      9 
     10 WebDriverWait(driver,60).until(EC.element_to_be_clickable((By.ID,"i0116")))
---> 11 driver.find_element_by_id("i0116").send_keys("u18ec013@svnitsuratg.onmicrosoft.com").click()
     12 
     13 WebDriverWait(driver,"idSIButton9")))

AttributeError: 'NoneType' object has no attribute 'click'

因为您根本无法在.click()的输出(即WebDriverWait)上调用None

以下代码可以正常工作:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome(executable_path='path/to/executable')

driver.get("https://login.microsoftonline.com")

WebDriverWait(driver,"i0116")))
driver.find_element_by_id("i0116").send_keys("your_emailid")

WebDriverWait(driver,"idSIButton9")))
driver.find_element_by_id("idSIButton9").click()

driver.find_element_by_id("i0118").send_keys("your_password")
WebDriverWait(driver,"idSIButton9")))
driver.find_element_by_id("idSIButton9").click()

WebDriverWait(driver,"idSIButton9")))
driver.find_element_by_id("idSIButton9").click()

对于您而言,只需将其更改为:

def signin(user,passwd):
    # find elements before passing information
    username = browser.find_element_by_name('loginfmt')
    username.send_keys(user)
    username.send_keys(Keys.ENTER)

    time.sleep(1)

    password = browser.find_element_by_name('passwd')
    password.send_keys(passwd)
    password.send_keys(Keys.ENTER)

    try:
        WebDriverWait(browser,"idBtn_Back")))
        browser.find_element_by_id("idSIButton9").click()

    except:
        sys.exit('Timeout for 2FA approval reached. Try again.')

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。