到此为止,我打开了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硒文档。我看到了键代码列表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。或者我可以手动向下翻页。但是滚动(至少在通常意义上来说)似乎不是问题,我仍然遇到该错误。也许是在我可以切换到的框架中,我不知道是哪个。
按钮当然是可见的。这只是常规的Google搜索页。
我可以找到该按钮,但是我看不到如何单击它,因为.click
对我不起作用。
已添加
回复评论,询问我Google推荐框是否使按钮模糊。我可以在浏览器中看到按钮没有被混淆,因为有时我已经手动完成了转义操作,或者单击了背景窗口(以消除这种情况。我使用的是IRB,因此手动运行每条语句,所以我有时间这样做)。但是我也使用代码进行了转义,并且转义功能可以摆脱建议框,但是在尝试单击按钮时仍然存在相同的错误
答案 0 :(得分:2)
这就是我告诉您使用WATIR的方式,如果您使用过WATIR,则不会出现此问题。您的代码中的问题,它不是在等待可见性。最近,Chrome驱动程序还添加了隐式等待点击,因此,如果您设置了隐式等待,它将等待可见性。否则,请移至WATIR,这是一个很好的包装程序,不需要通过驱动程序等待。在WATIR中,等待元素状态的操作是通过本地语言绑定发生的,因此请使用此硒代码
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
请记住,此硒代码不适用于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
答案 1 :(得分:1)
在评论中讨论此问题时,我编写了一些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合作以来,我自然就在等待)。而且我已经单击了外部或单击逃逸来摆脱弹出窗口。问题是,Jeff的回答使我意识到了这一点-即使弹出窗口消失了,仍然有两个带有btnK名称的按钮。因此,使用find_elements
而不是find_element
,然后在第二个运行.click
可以! (此外,将find_elements
(复数)用作name属性是有意义的,因为如此处答案中所述:https://stackoverflow.com/questions/5518458/does-a-name-attribute-have-to-be -unique-in-a-html-document。name属性不是唯一的/不是唯一的标识符。
答案 2 :(得分:0)
但是您可以使用javascript(将javascript发送到浏览器)进行点击。
b=driver.find_element(:name, "btnK")
driver.execute_script("arguments[0].click();",b)
Jeff解释了为什么javascript方法(带有selenium的selenium)可以在任一按钮上工作,而非javascript方法(没有javascript的硒)只能在一个按钮上工作,他写道:“两个按钮都可以,JS单击将单击任何元素,无论它在何处...或它是否可见,等等。Selenium旨在像用户一样与页面进行交互,因此由于错误而无法单击该元素。“