【问题标题】:Python + Selenium - Microsoft 2FAPython + Selenium - 微软 2FA
【发布时间】:2021-02-04 12:29:23
【问题描述】:

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

我尝试让 Selenium 等到保持登录页面上的“否”按钮元素出现(见下面的屏幕截图), 但它似乎不喜欢它。我看了一下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() 命令,但这似乎是一种非常愚蠢的做法。有人有什么建议吗?

【问题讨论】:

  • 链接到网站?
  • @Yatin URL 是 https://<companyName>.visualstudio.com/,但您会立即被重定向到登录页面,例如 - https://login.microsoftonline.com/9fdf2c7e-d190-4b8e-ba6b-2cd9be62632e/oauth2/authorize?client_id=<client_id and other sensitive information>

标签: python selenium two-factor-authentication


【解决方案1】:

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, 60).until(EC.element_to_be_clickable((By.ID, "idSIButton9")))

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

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

以下代码可以正常工作:

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, 60).until(EC.element_to_be_clickable((By.ID, "i0116")))
driver.find_element_by_id("i0116").send_keys("your_emailid")

WebDriverWait(driver, 60).until(EC.element_to_be_clickable((By.ID, "idSIButton9")))
driver.find_element_by_id("idSIButton9").click()

driver.find_element_by_id("i0118").send_keys("your_password")
WebDriverWait(driver, 60).until(EC.element_to_be_clickable((By.ID, "idSIButton9")))
driver.find_element_by_id("idSIButton9").click()

WebDriverWait(driver, 60).until(EC.element_to_be_clickable((By.ID, "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, 60).until(EC.element_to_be_clickable((By.ID, "idBtn_Back")))
        browser.find_element_by_id("idSIButton9").click()

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

【讨论】:

  • 感谢亚丁回复我!不幸的是,您发送的最后一个块不起作用。我仍然在超时。控制台立即抛出超时错误。
  • @Flu17 你没有使用finally correctlyfinally始终执行。因此,即使try 中的代码有效,finally 也会执行。立即查看代码
  • 哦,我明白了,是的,这行得通,谢谢。只是 try 部分仍然无法正常工作:(
  • "isn't working still" 尝试删除try 部分并让代码失败...这样您就可以知道错误是什么...将错误发送给我。 .
猜你喜欢
  • 2021-07-31
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 2021-10-29
  • 2017-10-21
  • 2018-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多