2

i'm probably not seeing something obvious, anyway i'd like to create functions to automatically extract text from an url already handled by a remote driver. I'd like to pass as a function arguments the xpath expression and the environment into which the remote driver could be found

library(RSelenium)

url="http://stackoverflow.com/search?q=r+program"
remdir<-remoteDriver(remoteServerAddr = "localhost", port = 4444, browserName = "firefox")
remdir$open()
remdir$navigate(url)
env<-environment()

#env should be the environment in wich remdir exist (remdir itself?)
#xp the xpath expression to evaluate in the form "//*"
fun.XpathExtractText<-function(xp,env)
{
  cat("\ncheck if session open\n")
  #look in env for an open session
  if ((eval(quote(is.na(remdir$sessionid)),envir = env)))
    stop("ERROR NO SESSION ID open new one")
  cat("session found\n")
  #accept xpath expression as is
  xp <- substitute(xp)
  txt<-c()
  #build the call to env
  cat("calling\n")
  call<-paste0("remdir$findElements(using = \"xpath\",\"",as.character(xp),"\")")
  tgt<-eval(as.name(call),envir = env)
  cat("Target locked\n")
  txt<-lapply(tgt,function(c){c$getElementText()})
  return(txt)
}

A possible call of this function could be fun.XpathExtractText("//*",env) But soon after the call build part here comes the error message:

Error in eval(expr, envir, enclos) : 
 object 'remdir$findElements(using = "xpath","//*")' not found 

but if i exectute in env directly the call extracted from the error message it will work.

tgt<-remdir$findElements(using = "xpath","//*")

I've tried to pass as environment also remdir itself as it is an environment, but that doesn't count at all, the function get stuck in the same point after the call build. What do i don't know?

Malacoda
  • 23
  • 3
  • `remdir` is a reference class object. You can pass it into your function. It will be passed by reference. You can then use it inside your function as you would outside. – jdharrison Nov 26 '16 at 18:19
  • Thanks a lot!!! anyway `if ((eval(quote(is.na(remdir$sessionid)),envir = env))))` it was working, that's why i was wondering why. Anyway you solved my problem, thanks again. – Malacoda Nov 26 '16 at 20:19

2 Answers2

0

Not sure what exactly you are trying to do. However eval doesn't seem the answer. You should pass the remoteDriver object into your function:

library(RSelenium)

url="http://stackoverflow.com/search?q=r+program"
remdir<-remoteDriver(remoteServerAddr = "localhost", port = 4444, browserName = "firefox")
remdir$open()
remdir$navigate(url)

fun.XpathExtractText<-function(xp, remdir)
{
  cat("\ncheck if session open\n")
  #look in env for an open session
  if (is.na(remdir$sessionid))
    stop("ERROR NO SESSION ID open new one")
  cat("session found\n")
  #accept xpath expression as is
  cat("calling\n")
  tgt <- remdir$findElements(using = "xpath",as.character(xp))
  cat("Target locked\n")
  txt<-lapply(tgt,function(c){c$getElementText()})
  return(txt)
}
jdharrison
  • 30,085
  • 4
  • 77
  • 89
0

Sorry i was not clear enough, anyway i was trying to build a function that could take an xpath and return the text of the element found, i'd like to extend this to grab also attribute value and other stuff to have everything into a one row command with the chance to change programmatically the xpath. A part of this this is a sort of excercise i've done to understand eval, substitute etc...at least that was the first thought.

Anyway this is working:

fun.XpathExtractText<-function(xp,dir)
{
  #look in env for an open session
  if (is.na(dir$sessionid))
    stop("ERROR NO SESSION ID open new one")
  #accept xpath expression as is
  xp <- substitute(xp)
  txt<-c()
  tgt<-dir$findElements(using = "xpath",xp)
  txt<-lapply(tgt,function(c){c$getElementText()})
  return(txt)
}

Just pass as dir the name of the remoteDriver.

Malacoda
  • 23
  • 3