【问题标题】:How to send keystrokes to a textbox that remains hidden until it's clicked on?如何将击键发送到在单击之前一直隐藏的文本框?
【发布时间】:2017-10-14 16:17:25
【问题描述】:

我正在尝试登录this site。但我什至无法用用户名填充文本框。

我试过了:

  • 隐式和显式等待

  • 执行 JavaScript

文本框的结构

用户名包含在td 标记中,可以使用其宽度属性定位。文本框本身由两个input 标签表示。第一个是隐藏的。两者都有style 属性。第一个的初始值为display: none;,当我单击文本框时,它变为display: inline-block;。第二个输入标签的style属性设置为display: none;。同样,一旦用户名文本框失去焦点,这两个都会切换。

等待

我尝试同时使用隐式和显式等待。实现显式等待的代码导致TimeoutException 错误:

wait = WebDriverWait(driver, 10)
elem_username = wait.until(EC.visibility_of_element_located((By.ID, 'txt_username')))

执行 JavaScript

input 标签都具有onfocusonchange 属性。我不关心后者(我的目标是首先将击键输入文本框)。 onfocus 的值为 SetEnd(this)。所以,我试图执行它。

我遇到的问题是我找不到任何可以帮助我执行 JavaScript 的文档。所以我在 StackOverflow 上查看了一些相关的答案。我首先尝试了这个:

elem_username = driver.find_element_by_id('txt_username')
driver.execute_script('SetEnd(this)')

当然,我知道这行不通,因为我指的不是元素。所以在浏览了几个问题之后,我了解到 execute_script 接受了参数。所以我修改了代码,它引发了一个错误,说脚本没有这样的功能:

driver.execute_script('arguments[0].SetEnd(this)', elem_username)

然后,我在execute_script 中看到了使用“click()”的答案;所以我也试过了:

driver.execute_script('arguments[0].click()', elem_username)

我猜,'click()' 仅适用于按钮。但是由于我必须在文本框中“单击”以使其成为焦点,所以我认为它会起作用。没有。

这是我在所有尝试中执行的最后一行,无一例外地不断引发ElementNotInteractableException 错误:

elem_username.send_keys('blahblahblah')

要求

如果我有更多的经验,这个网站上的问答当然会很棒。例如,有几个答案展示了显式等待,但其中大多数旨在解决 OP 的问题,因此它们仅包含代码的相关部分。我很难理解他们。

我想解决这个问题(登录网站),但我也想学习正确使用 selenium。我之前没有在任何其他语言(如 Java)中使用过它。官方文档很好,但我无法使用它来解决这个问题。所以我想要一个更适合初学者的教程。

【问题讨论】:

    标签: javascript python selenium selenium-webdriver web-scraping


    【解决方案1】:

    这对我有用:

    # Force the element to be displayed (noticed style.display = "none")
    # Yes, I know you can see it, but selenium thinks it's not displayed.
    driver.execute_script('document.getElementsByName("txt_username")[0].style.display="block"')
    
    elem_username.send_keys('your name')
    

    【讨论】:

    • 它也对我有用。你知道为什么会出现两个文本框吗? imgur.com/a/yWcYb
    • 我不确定他们在幕后使用了什么样式,以及他们所有的交互式 javascript 代码对元素做了什么。显示对象的镜子确实很奇怪。页面源不显示重复条目。
    • 您的解决方案解决了这个问题。但是,正如我所说的那样,我想以适当的方式学习这一点。你能告诉我应该怎么做吗?
    【解决方案2】:

    所以您已经很好地概述了所有内容,并且您似乎对它有很好的理解。诀窍是首先单击第二个input,然后将密钥发送到第一个input,因为它随后被聚焦。 (我确实发现单击包含 td 的内容也适用于 Chrome,但浏览器在这方面有所不同,此页面的目的是您单击第二个输入)。一个简单的解决方案如下:

    real, readonly = driver.find_elements_by_css_selector("input[onfocus*='SetEnd']")
    readonly.click()
    real.send_keys('hi')
    

    如果您对此有任何疑问,我可以尝试提供帮助。

    【讨论】:

    • 那行得通。我仍在寻找一种方法来学习正确使用硒,这就是为什么我没有接受你的任何一个答案。我对他们投了赞成票,但他们独自解决了我的临时问题。
    • 我最终接受了 Ron 的回答(因为他是第一个),因为我在元网站上看到了几篇帖子,发现我不应该要求“教程”。所以,既然这个特定的问题得到了解决,这个问题就没有太大的意义了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    相关资源
    最近更新 更多