Search code examples
rtry-catchrvestrseleniumr-s4

RSelenium: Try if findElement succeeds, then click on it, error: "object of type 'S4' is not subsettable"


I'm scraping https://www.tandfonline.com/loi/sabo20 with RSelenium.

I want to click on each li that have texts ending with the years 2015 until 2021. The xpath works well.

A year (e.g. 2021) might be missing, which is why I use a try()-approach.

  URL <- "https://www.tandfonline.com/loi/sabo20"

  # open RSelenium
  rD <- RSelenium::rsDriver(browser = "chrome", chromever = "90.0.4430.24", port = 4546L, verbose = F)

  remDr <- rD[["client"]]
  remDr$navigate(URL)
  Sys.sleep(4)

  for (yyyy in c(2015:2021)) {
    error <- "Error : \t Summary: NoSuchElement\n \t Detail: An element could not be located on the page using the given search parameters.\n \t class: org.openqa.selenium.NoSuchElementException\n\t Further Details: run errorDetails method\n"

    volumes <- try(unlist(
      remDr$findElement(
        using = "xpath",
        paste0(
          "//li[substring(@id, string-length(@id) - string-length('",
          yyyy,
          "') +1) = '",
          yyyy,
          "']/div"
        )
      )
    ))
    
      if(volumes[1] == error)
        break;
    
    volumes$clickElement()
  }

Unfortunately, if(volumes[1] == error) leads to an error if findElement() had succeeded:

Error in volumes[1] : object of type 'S4' is not subsettable

How then can I check whether remDr$findElement() succeeded before I clickElement() on it?


Solution

  • The solution could be trycatch

    Below an example.

    URL <- "https://www.tandfonline.com/loi/sabo20"
    
    # open RSelenium
    rD <- RSelenium::rsDriver(browser = "chrome", chromever = "90.0.4430.24", port = 4546L, verbose = F)
    
    remDr <- rD[["client"]]
    remDr$navigate(URL)
    Sys.sleep(4)
    
    for (yyyy in c(1983:2021)) {
    tryCatch(expr = {   
      volumes <- unlist(
        remDr$findElement(
          using = "xpath",
          paste0(
            "//li[substring(@id, string-length(@id) - string-length('",
            yyyy,
            "') +1) = '",
            yyyy,
            "']/div"
          )
        )
      )
      volumes$clickElement()
      Sys.sleep(4)
      },
      error =function(e){          
        message("if you want you can break, but it not necessary")
      })
    }