Rselenium 无法单击所有单选按钮(只有其中一些)

Rselenium can not click all radiobutton (only some of them)

我想通过 RSelenium 获得一些抓取技巧,但我遇到了困难。

我想为这个 page 中的评论选择语言。但是当出现弹出式单选按钮列表时,我设法点击了其中的一些而不是其他的。我想我确实得到了正确的元素。这是我尝试过的:

library(RSelenium)

remDr <- remoteDriver(
  remoteServerAddr = "localhost",
  port = 4445L,
  browserName = "firefox"
)

url <- "https://www.tripadvisor.com/Restaurant_Review-g187438-d12718258-Reviews-Prohobitox-Malaga_Costa_del_Sol_Province_of_Malaga_Andalucia.html"

remDr$navigate(url)

# click more language popup
webElems <- remDr$findElements(using = "css selector", ".taLnk") # taLnk is for dropdown like
webElemstext <- unlist(lapply(webElems, function(x) {x$getElementText()}))
webElems[[which(webElemstext == "More languages")]]$clickElement() 

我尝试通过这种方式获取单选按钮:

langues <- remDr$findElements(using = "class", "ui_radio")
langues_txt <-  unlist(lapply(langues, function(x) {x$getElementText()}))

> langues_txt
 [1] "All languages"  "English (120)"  "Spanish (66)"   "Norwegian (25)" "All languages" 
 [6] "English (120)"  "Spanish (66)"   "Norwegian (25)" "Dutch (22)"     "Swedish (13)"  
[11] "French (12)"    "German (10)"    "Italian (7)"    "Danish (3)"     "Finnish (2)"   
[16] "Portuguese (1)"

奇怪的是我可以点击最后一个单选按钮,但不能点击其他单选按钮,而且我不明白。如果我尝试点击芬兰语:

langues[[14]]$clickElement() 
remDr$screenshot(display = TRUE)

什么都没发生。但是葡萄牙语:

langues[[16]]$clickElement() 
remDr$screenshot(display = TRUE)

在这里它起作用了。 我看不出这两种情况有什么区别,所以我没有找到单击弹出窗口中的任何单选按钮的解决方案。

有什么想法吗?

编辑

我试图点击所有的。我可以单击 "All language"、"English"、"Norwegian" 和 "Portuguese"。 None 的其他人工作,即使使用建议的解决方案:

BigDataScientist 解决方案

我确实加载了弹出菜单,我之前删除了cookies:

remDr$deleteAllCookies()
remDr$navigate(url)

# click more language
webElems <- remDr$findElements(using = "css selector", ".taLnk") # taLnk est le css pour etendre des menus.
webElemstext <- unlist(lapply(webElems, function(x) {x$getElementText()}))
webElems[[which(webElemstext == "More languages")]]$clickElement() 

这是给出的解决方案

langues <- remDr$findElements(
  using = "xpath", 
  value = "/html/body/div/div/div/div[@class = 'ui_radio item']"
)
langues_txt <-  unlist(lapply(langues, function(x) {x$getElementText()}))
langues[[8]]$clickElement() # It should be german
remDr$screenshot(display = TRUE)

结果如下:

确实在这里我只有 12 种语言,但我仍然无法点击我想要的按钮。

supputuri 解决方案

它对我也不起作用:我都试过了:

langElement <- remDr$findElement(using = "css", ".more-options .ui_radio.item:nth-of-type(8) input")
langElement$clickElement()
remDr$screenshot(display = TRUE)

langElement <- remDr$findElement(using = "css", ".more-options div[data-tracker='German'] input")
# click on language radio button
langElement$clickElement()
remDr$screenshot(display = TRUE)

none 有效:

问题根源:

使用 class 选择器,您还可以捕获主页的平板电脑版本 (?) 的潜在语言设置。请看下面的截图:

在第一行中,您会看到 class choice is-shown-at-tablet

解决方法:

您应该可以通过修改选择器(并排除平板电脑选项)来避免该问题。一种方法是使用完整的 xpath(因为它不同于平板电脑选项的 xpath)。

xpath 将是:

/html/body/div/div/div/div[@class = 'ui_radio item']

一个测试:

从您的可重现性代码开始:

url <- "https://www.tripadvisor.com/Restaurant_Review-g187438-d12718258-Reviews-Prohobitox-Malaga_Costa_del_Sol_Province_of_Malaga_Andalucia.html"

remDr$navigate(url)
# click more language popup
webElems <- remDr$findElements(using = "css selector", ".taLnk") # taLnk is for dropdown like
webElemstext <- unlist(lapply(webElems, function(x) {x$getElementText()}))
webElems[[which(webElemstext == "More languages")]]$clickElement()

然后使用新选择器查找元素:

langues <- remDr$findElements(
  using = "xpath", 
  value = "/html/body/div/div/div/div[@class = 'ui_radio item']"
)

langues_txt <-  unlist(lapply(langues, function(x) {x$getElementText()}))
> langues_txt
[1] "All languages"  "English (120)"  "Spanish (67)"   "Norwegian (25)" "Dutch (22)"     "Swedish (13)"  
[7] "French (12)"    "German (10)"    "Italian (7)"    "Danish (3)"     "Finnish (2)"    "Portuguese (1)"

如您所见,您从 16 种语言选项减少到 12 种语言选项(不包括双打),并且只得到您在屏幕截图中看到的一种。

您可以测试点击它们(例如德语):

langues[[8]]$clickElement()

注:

可能你已经知道了,但为了完整起见:如果你想测试多种语言并且已经点击了一种,你必须再次弹出语言弹出窗口 "up",通过 运行我评论后的代码部分 "Starting with your code for reproducibility:".

编辑:

很遗憾,我无法重现您的错误。你能不能试试这个:

langues <- remDr$findElements(
  using = "xpath", 
  value = "/html/body/div/div/div/div[@class = 'ui_radio item']/label[contains(text(), 'German')]"
)[[1]]$clickElement()

langues <- remDr$findElements(
      using = "xpath", 
      value = "/html/body/div/div/div/div[@class = 'ui_radio item']/label[contains(text(), 'German')]"
    )
remDr$executeScript("arguments[0].click();", args = langues[1])

让我把事情简单明了。

我建议 select 使用下面的语言 css。

选项 1:使用 CSS 语言

.more-options div[data-tracker='Finnish'] input

这是脚本。

# find element using css
langElement <- remDr$findElement(using = "css", ".more-options div[data-tracker='XXXchangeLangHereXXX'] input")
# click on language radio button
langElement$clickElement()

截图:

选项 2:使用 CSS 基于索引

如果你想 select 索引语言(我相信这不是你正在寻找的)你可以使用下面的方法。

# this css will get `Finnish` radio button
.more-options .ui_radio.item:nth-of-type(11) input 

这是脚本

# find element using css
langElement <- remDr$findElement(using = "css", ".more-options .ui_radio.item:nth-of-type(XXXChangeIndexHereXXX) input")
# click on language radio button
langElement$clickElement()

截图:

当单击的容器中的名称不够长时,单选按钮不会接收到单击事件。

单击某个元素时,驱动程序会将所有事件发送到位于所提供元素中心顶部的元素。

但对于您的情况和大多数元素,容器的中心点是容器本身,而不是预期的单选按钮。

如果您想可靠地单击单选按钮,请改为单击 <label> :

item <- remDr$findElement(using = 'css selector', "[data-tracker='German'] label")
item$clickElement()

或通过带有 XPath 的文本:

item <- remDr$findElement(using = 'xpath', '//label[contains(.,"German")]')
item$clickElement()