【问题标题】:Rselenium can not click all radiobutton (only some of them)Rselenium 无法单击所有单选按钮(仅其中一些)
【发布时间】:2019-07-04 21:52:32
【问题描述】:

我正在尝试使用RSelenium 获得一些抓取技巧,但我遇到了一个困难。

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

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)

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

有什么想法吗?

编辑

我试图点击所有这些。我可以单击“所有语言”、“英语”、“挪威语”和“葡萄牙语”。即使使用建议的解决方案,其他任何一个都不起作用:

BigDataScientist 解决方案

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

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)

没有成功:

【问题讨论】:

    标签: javascript r selenium web-scraping rselenium


    【解决方案1】:

    问题根源:

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

    在第一行中,您会看到 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()
    

    注意:

    您可能已经知道了,但为了完整起见:如果您想测试多种语言并已经单击了一种语言,则必须通过在我的评论“开始”之后运行代码部分来再次“弹出”语言弹出窗口使用您的代码进行重现性:"。

    编辑:

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

    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])
    

    【讨论】:

    • 谢谢!我明天会测试它,但它看起来正是我需要的。了解完整 xpath 的最佳方法是什么? Firefox 的元素检查器(或页面源)? xpath 是否有 gadgetSelector 之类的东西?
    • 不行,很抱歉,我还是遇到了同样的问题,我只能点击其中的几个,大多数都不起作用。
    • 你能在clickElement之后给一个截图输出吗?在我的问题的编辑中查看我的
    • 对不起,我两天没上网了。不幸的是,我无法重现该错误。运行代码后,我只看到德国 cmets。我在帖子末尾进行了编辑。也许我们可以尝试直接查询元素并单击它。
    • 是的,最后一次编辑有效。实际上,它必须使用标签,而不是输入。我把赏金给了 Florent B,他之前找到了答案,并给出了解释。但是非常感谢所有的投入
    【解决方案2】:

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

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

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

    如果您想可靠地单击单选按钮,请改为单击&lt;label&gt;

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

    或者通过带有 XPath 的文本:

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

    【讨论】:

    • 哇!!这似乎是有道理的。它是否取决于屏幕分辨率(这就是 BigDataScientist 和 suputuri 无法重现我的错误的原因?我使用的是 3200 x 1800 像素)。我会在稍后尝试,但感谢您的输入
    • @denis,我没有检查分辨率是否对宽度有影响,但无论如何如果在&lt;label&gt;上执行它不会影响点击。
    • 是的,就是这样!
    【解决方案3】:

    让我把事情简单明了。

    我建议使用下面的 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

    如果您想按索引选择语言(我相信这不是您正在寻找的),您可以使用以下方法。

    # 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()
    

    截图:

    【讨论】:

    • 感谢您的回答!您能否为您的 css 的 .more-options par 提供一些解释?我不确定是否正确理解它。另外,您能否告诉我与 BigDataScientist 答案(即使用 xpath)相比有什么优势?您的解决方案是否有可能遇到我所面临的同类问题,即获得与我试图获得的语言设置不同的语言设置?
    • 你真的设法选择了单选按钮吗?你能在clickElement()之后给个截图吗?我无法让它工作
    • 我的机器上没有 ruby​​ selenium,但能够使用我发布的 css 成功选择单选按钮。添加截图供您参考。
    • 嗯。你试试js点击而不是clickElement(),应该会有所不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多