【问题标题】:How can I prompt for input using Selenium/Webdriver and use the result?如何使用 Selenium/Webdriver 提示输入并使用结果?
【发布时间】:2011-11-17 22:30:03
【问题描述】:

我想允许用户输入并根据它做出一些决定。如果我这样做:

driver.execute_script("prompt('Enter smth','smth')")

我得到一个很好的提示,但我不能使用它的价值。有没有办法向用户显示一个输入框,并使用那里输入的值?

编辑:这是我的脚本:

from selenium.webdriver import Firefox

if __name__ == "__main__":
    driver = Firefox()
    driver.execute_script("window.promptResponse=prompt('Enter smth','smth')")
    a = driver.execute_script("var win = this.browserbot.getUserWindow(); return win.promptResponse")
    print "got back %s" % a

这会退出并出现以下异常:

    a = driver.execute_script("var win = this.browserbot.getUserWindow(); return win.promptResponse")
  File "c:\python26\lib\site-packages\selenium-2.12.1-py2.6.egg\selenium\webdriver\remote\webdriver.py", line 385, in ex
ecute_script
    {'script': script, 'args':converted_args})['value']
  File "c:\python26\lib\site-packages\selenium-2.12.1-py2.6.egg\selenium\webdriver\remote\webdriver.py", line 153, in ex
ecute
    self.error_handler.check_response(response)
  File "c:\python26\lib\site-packages\selenium-2.12.1-py2.6.egg\selenium\webdriver\remote\errorhandler.py", line 110, in
 check_response
    if 'message' in value:
TypeError: argument of type 'NoneType' is not iterable

我做错了什么?

编辑:我尝试像 prestomanifesto 建议的那样做,这是输出:

In [1]: from selenium.webdriver import Firefox

In [2]: f = Firefox()

In [3]: a = f.ex
f.execute              f.execute_async_script f.execute_script

In [3]: a = f.execute_script("return prompt('Enter smth','smth')")

In [4]: a
Out[4]: {u'text': u'Enter smth'}

In [5]: a
Out[5]: {u'text': u'Enter smth'}

In [6]: class(a)
  File "<ipython-input-6-2d2ff4f61612>", line 1
    class(a)
         ^
SyntaxError: invalid syntax


In [7]: type(a)
Out[7]: dict

【问题讨论】:

    标签: python selenium webdriver


    【解决方案1】:

    希望这对其他人有所帮助:

    # selenium (3.4.1)  python (3.5.1)
    driver.execute_script("var a = prompt('Enter Luffy', 'Luffy');document.body.setAttribute('data-id', a)")
    time.sleep(3)  # must 
    print(self.driver.find_element_by_tag_name('body').get_attribute('data-id'))   # get the text
    

    【讨论】:

      【解决方案2】:

      您在javascript中使用提示框是正确的。但是提示框值应该分配给一个全局变量,然后你可以稍后使用这个变量。 像这样:

      driver.execute_script("window.promptResponse=prompt('Enter smth','smth')")

      然后从同一个全局变量中检索值。

      a = driver.execute_script("var win = this.browserbot.getUserWindow(); return win.promptResponse")
      

      你可能需要强制返回。

      希望这会有所帮助。

      【讨论】:

      • 我用运行您的代码的结果更新了我的问题。你能发现我做错了什么吗?
      【解决方案3】:

      我知道这是一个老问题,但我也有同样的问题,这对我有用:感谢@Devin

      from selenium.common.exceptions import UnexpectedAlertPresentException
      
      while True:
          try:
              driver.execute_script("var a = prompt('Enter Luffy', 'Luffy');document.body.setAttribute('user-manual-input', a)")
              sleep(5)  # must 
              print(driver.find_element_by_tag_name('body').get_attribute('user-manual-input')) # get the text
              break
      
           except (UnexpectedAlertPresentException):
              pass
      

      提示将等待 5 秒输入。如果没有提供输入,它会提示用户再次输入。

      【讨论】:

        【解决方案4】:

        根据其他答案,我构建了以下适用于我的代码:

        
        def is_alert_present(driver):
            try:
                driver.switch_to.alert
                return True
            except exceptions.NoAlertPresentException:
                return False
        
        
        def prompt_user(driver, text):
        
            driver.execute_script('var a = prompt ("{}");document.body.setAttribute("data-id", a)'.format(text))
            while is_alert_present(driver):
                sleep(4)
            v = driver.find_element_by_tag_name('body').get_attribute('data-id')
        
            return v if v != 'null' else None
        
        

        【讨论】:

          【解决方案5】:

          Tkinter 是一个基于 GUI 的库,您可以使用它在运行时从用户那里获取输入。这将使程序处于等待状态,除非用户输入信息。对于预先设计的对话框,您可以参考这个link。虽然它迟到了,但它可能会帮助别人。

          【讨论】:

          • Tkinter 在没有 GUI 的生产服务器中如何工作?
          【解决方案6】:

          如果你们像我一样使用 selenium 2.28,这就像@Baz1nga 所说的那样

          //Open the prompt inbox and setup global variable to contain the result
          WebDriver driver = new FirefoxDriver();
          JavascriptExecutor js = (JavascriptExecutor) driver;
          js.executeScript("window.promptResponse = prompt(\"Please enter captcha\");");
          
          //Handle javascript prompt box and get value. 
          Alert alert = driver.switchTo().alert();
          try {
            Thread.sleep(6000);
          } catch (Exception e)
          {
            System.out.println("Cannot sleep because of headache");
          }
          alert.accept();
          String ret = (String) js.executeScript("return window.promptResponse;");
          

          【讨论】:

          • 你不应该只接受前面的答案并将其移植到 Javascript 以解决有关 Python 的问题。
          【解决方案7】:

          为什么不直接返回值呢?

          if __name__ == "__main__":
              driver = Firefox()
              a = driver.execute_script("return prompt('Enter smth','smth')")
              print "got back %s" % a
          

          在 C# 中为我工作。诚然,它是一个稍旧的 Selenium 版本,但我不希望 execute_script 函数有太大变化。

          【讨论】:

          • 问题是,execute_script 立即返回。在我输入输入之前它不会阻塞。查看我的编辑。
          【解决方案8】:

          你可以使用here建议的技术

          基本思路是:

          • 发出 Selenium 命令直到您要捕获用户输入。
          • 使用raw_input() 在控制台窗口中获取用户输入
          • 继续您的 Selenium 命令

          以 Python 为例:

          #Navigate to the site
          driver.Navigate().GoToUrl("http://www.google.com/")
          #Find the search box on the page
          queryBox = self.driver.FindElement(By.Name("q"))
          #Wait for user text input in the console window
          text = raw_input("Enter something")
          #Send the retrieved input to the search box
          queryBox.SendKeys(text)
          #Submit the form
          queryBox.Submit()
          

          【讨论】:

          • 我想让它基于 GUI。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-29
          • 2021-04-29
          • 1970-01-01
          • 1970-01-01
          • 2013-05-05
          • 1970-01-01
          相关资源
          最近更新 更多