4

I am using RSelenium to navigate to sites and interact with the elements.

Question: using RSelenium, how can I read the list of options in a dropdown menu so that I can identify the latest month available and use that to set the dropdown to the correct value?

On a certain site a dropdown menu is provided for the user to set the month of the year, thus defining the end point of a date range used in turn to display or download monthly data. As additional months of data become available through the year, the options in the dropdown change.

Dropdown menu options

By the end of July the dropdown will have 6 options, January to June. Note that the data for a particular month is released about 4-6 weeks after the end of that month, so you do not get June's data until late July, and so on. I can set the values using numbers 1 to 12 without any problems, provided that the dropdown actually contains the corresponding option.

If, for example, the data for July has not yet been published (that is, if July has not yet appeared in the dropdown list of options) and if I try to set the dropdown to '7' I will get an error, which I want to avoid. The data does not appear on a regular schedule, so I cannot simply assume that the data for month X will appear on date Y.

I believe that with Selenium itself there is a helper class available, but I'm not sure whether I can access that through RSelenium.

Example code follows - may be a bit ropey as I'm still far from familiar with the package.

library(RSelenium)
RSelenium::checkForServer()
RSelenium::startServer()

remDr <- remoteDriver(remoteServerAddr = "localhost",
                      port = 4444,
                      browserName = "firefox"
                      )
remDr <- remoteDriver()
Sys.sleep(5)
remDr$open()
remDr$getStatus()

remDr$navigate("http://jamaserv.jama.or.jp/newdb/eng/index.html")

## Switch to left frame
frameElems <- remDr$findElements(using = "tag name", "frame")
sapply(frameElems, function(x){x$getElementAttribute("src")})
remDr$switchToFrame(frameElems[[1]])

webElem <- remDr$findElement(using = 'xpath', "//select[@name='txtTargetToMm']")

## Use javascript to set values
script <- paste0("arguments[0].value = '", 2, "'; arguments[0].onchange();") # set to February
remDr$executeScript(script, list(webElem))
webElem$getElementAttribute('value')    # check to see if it worked
2
  • Sometimes I like to pull the curl request directly from the development console and just wrap it in system. It's not pretty, but it almost always works. Open the console, switch to the network tab, perform your action, right click on element with your data, Copy as curl. Commented Jul 24, 2015 at 17:56
  • Thanks for that; interesting tip. Commented Jul 24, 2015 at 18:52

1 Answer 1

6

You can use the selectTag method to interact with HTML select elements:

library(RSelenium)

rD <- rsDriver(verbose = F)
remDr <- rD$client
remDr$navigate("http://jamaserv.jama.or.jp/newdb/eng/index.html")

## Switch to left frame
frameElems <- remDr$findElements(using = "tag name", "frame")
sapply(frameElems, function(x){x$getElementAttribute("src")})
remDr$switchToFrame(frameElems[[1]])

webElem <- remDr$findElement(using = 'xpath', "//select[@name='txtTargetToMm']")
opts <- webElem$selectTag()

> opts$text
[1] "JANUARY"   "FEBRUARY"  "MARCH"     "APRIL"     "MAY"       "JUNE"      "JULY"      "AUGUST"   
[9] "SEPTEMBER" "OCTOBER"   "NOVEMBER"  "DECEMBER" 
> opts$value
[1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12"
> opts$selected
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE

# select the third month (march)
opts$elements[[3]]$clickElement()

# check whether it is selected
opts <- webElem$selectTag()
opts$selected

> opts$selected
[1] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

rm(rD)
gc()
Sign up to request clarification or add additional context in comments.

1 Comment

If I try to run your code, but I get an error Error: attempt to apply non-function when trying to execute opts$elements[[3]]$clickElement().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.