【问题标题】:In Ruby, with selenium, difficulty clicking Google Search在 Ruby 中,使用 selenium,难以点击 Google 搜索
【发布时间】:2019-05-27 00:03:11
【问题描述】:

我已经走到这一步了,打开 firefox 浏览器,导航到 google,然后找到 google 搜索元素

irb(main):001:0> require 'selenium-webdriver'
=> true

irb(main):002:0> driver = Selenium::WebDriver.for:firefox
=> #<Selenium::WebDriver::Firefox::Marionette::Driver:0x..fb3c81796cc82b708 browser=:firefox>

irb(main):003:0> driver.navigate().to("http://www.google.com")
=> nil

irb(main):188:0> driver.find_element(:name, "q").send_keys "fff"
=> nil    

irb(main):112:0> driver.find_element(:name, "btnK");
=> #<Selenium::WebDriver::Element:0x5fb450f4379c50ce id="d767311c-27a2-3544-8f11-e4edc9736588">

irb(main):113:0> driver.find_element(:name, "btnK").attribute('value');
=> "Google Search"

但我无法点击它!

irb(main):114:0> driver.find_element(:name, "btnK").click
Traceback (most recent call last):
       16: from /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/remote/w3c/bridge.rb:552:in `execute'
       15: from /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/remote/bridge.rb:166:in `execute'
       14: from /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/remote/http/common.rb:62:in `call'
       13: from /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/remote/http/default.rb:104:in `request'
       12: from /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/remote/http/common.rb:84:in `create_response'
       11: from /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/remote/http/common.rb:84:in `new'
       10: from /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/remote/response.rb:32:in `initialize'
        9: from /usr/local/lib/ruby/gems/2.5.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/remote/response.rb:69:in `assert_ok'
        8: from clickElement@chrome://marionette/content/listener.js:1209:5
        7: from navigate@chrome://marionette/content/listener.js:409:13
        6: from navigate/<@chrome://marionette/content/listener.js:410:13
        5: from clickElement/<@chrome://marionette/content/listener.js:1210:14
        4: from interaction.clickElement@chrome://marionette/content/interaction.js:130:11
        3: from webdriverClickElement@chrome://marionette/content/interaction.js:159:11
        2: from ElementNotInteractableError@chrome://marionette/content/error.js:286:5
        1: from WebDriverError@chrome://marionette/content/error.js:178:5
Selenium::WebDriver::Error::ElementNotInteractableError (Element <input name="btnK" type="submit"> could not be scrolled into view)
irb(main):115:0> 

它说元素“无法滚动到视图中”!

我可以做driver.find_element(:tag_name, "body").send_keys :page_down;,它会向下翻页。提到了查看 send_keys https://www.rubydoc.info/gems/selenium-webdriver/Selenium%2FWebDriver%2FElement%3Asend_keys 的 ruby​​ selenium 文档。我看到了一个关键代码列表 https://www.rubydoc.info/gems/selenium-webdriver/Selenium/WebDriver/Keys#KEYS-constant 。并且还列出了https://github.com/SeleniumHQ/selenium/blob/master/rb/lib/selenium/webdriver/common/keys.rb。或者我可以手动向下翻页。但是滚动(至少在这个术语的正常意义上)似乎不是问题,我仍然得到那个错误。也许它在我可以切换到的框架中,但我不知道是哪个。

按钮当然是可见的。这只是一个普通的谷歌搜索页面。

我可以很好地找到该按钮,但我看不到如何单击它,因为 .click 不适合我。

添加

回复评论,询问我谷歌建议框是否混淆了按钮。我可以在浏览器中看到该按钮没有被混淆,因为有时我已经手动完成了转义,或者单击了背景窗口(以摆脱它。我正在使用 IRB,因此手动运行每个语句,所以我有时间这样做)。但是我也确实使用代码进行了转义,并且转义可以摆脱建议框,但尝试单击按钮时仍然出现同样的错误

【问题讨论】:

  • 是否有搜索建议框 - 会混淆按钮?您可以通过向搜索框发送 ESC 键(我相信您可以轻松找到它的代码;)来隐藏它。
  • @Todor 我可以在浏览器中看到该按钮没有被混淆......;因为有时我已经手动完成了转义。但是我也确实使用代码进行了转义,并且转义可以摆脱建议框,但是尝试单击按钮时仍然出现同样的错误
  • 您可以通过传递查询字符串直接导航到 SERP:https://www.google.com/search?q=foo
  • @CoreyGoldberg 你真的相信问这个问题的人不会知道吗?你向我展示的唯一一件事就是有一个缩写 SERP。接下来,您将向 IT 技术人员发布 cmets,告诉他们可以重新启动 Windows。
  • @barlop,“这个级别的问题”?我认为介于“完全新手”和“困惑的初学者”水平之间。所以回答你的问题...是的,我真的相信这一点。

标签: ruby selenium selenium-webdriver


【解决方案1】:

但您可以使用 javascript 进行点击(将 javascript 发送到浏览器)。

b=driver.find_element(:name, "btnK")

driver.execute_script("arguments[0].click();",b)

Jeff 解释了为什么 javascript 方法(带有 javascript 的 selenium)适用于任一按钮,但非 javascript 方法(没有 javascript 的 selenium)仅适用于一个按钮,他写道“两个按钮都可以工作,JS 点击会点击任何元素,无论它在哪里......或者它是否可见等。Selenium 被设计为像用户一样与页面交互,因此由于错误而无法点击该元素。”

【讨论】:

  • 来源是 DevNami youtube.com/watch?v=rL7V9x94OwM 的这个 youtube 视频。 (通常在他的系列中的任何视频中跳到 1:20 以跳过他输入像 require ... 这样的行并输入他所有的初始化代码都是有用的)
  • 另外,stackoverflow.com/questions/7565562/… 也有一个类似的简单示例
  • 杰夫的回答(加上我添加的说明),解释了为什么我在我的问题中所做的点击不起作用,但没有解释为什么(相反),这个点击有效!
【解决方案2】:

这就是我告诉你使用 WATIR,如果你使用了 WATIR,这个问题就不会出现。您的代码中的问题,它不等待可见性。最近 Chrome 驱动程序也添加了隐式等待点击,所以如果你设置隐式等待它会等待可见性。否则转到 WATIR,它是一个很好的包装器,它不通过驱动程序等待,在 WATIR 中等待元素状态发生在本地语言绑定中,所以使用这个 selenium 代码

require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome
driver.manage.timeouts.implicit_wait = 10
driver.navigate().to("http://www.google.com")
driver.find_element(:name, "q").send_keys "fff"
driver.find_element(:name, "btnK").click

请记住,此 selenium 代码不适用于 Firefox,因为尚未为 Firefox 添加隐式等待点击。

由于 WATIR 正在处理来自本地语言绑定的时间,因此无论您使用 Chrome 还是 Firefox,它都可以完美运行

WATIR 代码(默认为 Chrome)

require 'watir'
b=Watir::Browser.new
b.goto 'www.google.com'
b.text_field(name: 'q').set 'fff'
b.button(name: 'btnK').click

如果你想驱动 Firefox

b=Watir::Browser.new :firefox

【讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • @YvetteColomb 在被删除之前会持续多久?
  • @barlop 聊天将无限期地留在那里。
【解决方案3】:

在 cmets 中讨论这个问题时,我写了一些 C# 代码来演示我们如何在 C# 中等待可点击

new WebDriverWait(Driver, TimeSpan.FromSeconds(5)).Until(ExpectedConditions.ElementToBeClickable(By.Name("btnK"))).Click();

在编写我发布的 C# 代码的过程中,我想我明白了问题所在。当您开始在搜索框中输入内容时,会出现一个下拉列表,其中包含建议的搜索。这涵盖了您尝试单击的“Google 搜索”按钮......但另一个“Google 搜索”按钮出现在下拉列表本身的底部。您应该打印 (:name, "btnK") 元素的计数...我假设它将打印 2(如果添加了适当的等待)。从那里,您只需单击顶部的那个。

另一种选择是在搜索字符串的末尾发送一个 \r\n 并避免整个问题...或者您可以导航到最终的搜索 URL 并节省更多的麻烦和时间。

添加了来自 barlop 的注释

澄清一下,这与显示的建议弹出窗口无关(并且必须摆脱弹出窗口).. 与等待无关(因为我与 IRB 合作,我自然而然地等待)。而且我已经在外面点击或点击逃脱以摆脱弹出窗口。问题是,杰夫的回答提醒了我这一点——即使弹出窗口消失了,仍然有两个带有该 btnK 名称的按钮。因此,使用find_elements 而不是find_element,并在第二个上运行.click 有效! (另外,使用find_elements(复数)作为名称属性是有道理的,因为正如这里的答案所述https://stackoverflow.com/questions/5518458/does-a-name-attribute-have-to-be-unique -in-a-html-document。name 属性不是唯一的/不是唯一的标识符。

【讨论】:

  • javascript 工作很奇怪!(请参阅我发布的部分答案),'因为在单击不起作用的同一个按钮上完成了!
  • @barlop 这两个按钮都可以工作,JS 点击将点击任何元素,无论它在哪里......或者它是否可见等。Selenium 被设计为与页面交互用户会因为错误而无法点击该元素。
  • 有趣。看看没有 javascript 和 C# 的 selenium,我认为 C# 在没有等待的情况下会给出一个元素不可见的异常。但是说一个等待。然后另一个有趣的想法是,在 C# 中我认为可能是相反的,所以第一个按钮是我想要单击的那个。如果我尝试单击第二个,那么它会给出状态元素引用异常。 (无论如何,不​​重要,而且我现在对 VS 有一些问题,所以不能轻松地仔细检查)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 2017-10-27
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
  • 1970-01-01
相关资源
最近更新 更多