2015-04-09 2 views
1

Я разворачиваю previous question о синтаксическом анализе html, чтобы задать вопрос о пустых значениях. Предположим, что у меня есть пустые значения для некоторых переменных, которые я вытягиваю из HTML. Есть несколько переменных, которые могут быть пустыми, поэтому я хочу систематический подход к их обработке (цикл или функция).Назначение переменных значений программно во время разбора html

Этот вопрос действительно касается назначения переменных программным образом, и большая часть информации, которую я нашел, предлагает избегать использования eval(parse(text, но я не уверен, как его заменить в этом случае. У меня есть следующий HTML:

html <- 
'<!DOCTYPE html> 
<html> 
    <body> 
     <div class="foo"> 
      <div class="fooname">Name of 1st foo</div> 
      <div class="abc">ABC value only present here</div> 
      <span>1st span in 1st foo</span> 
      <span>2nd span in 1st foo</span> 
     </div> 

     <div class="foo"> 
      <div class="fooname">Name of 2nd foo</div> 
      <span>Only 1 span in 2nd foo</span> 
     </div> 
    </body> 
</html>' 

Вот синтаксический:

library(XML) 

html.parse <- htmlParse(html) 

myFunc <- function(x){ 
    fooname <- xpathSApply(x, "./div[@class='fooname']", fun = xmlValue) 
    abc <- xpathSApply(x, "./div[@class='abc']", fun = xmlValue) 
    span <- xpathSApply(x, "./span", fun = xmlValue) 

    df <- data.frame(fooname, abc, Span1 = span[1], Span2 = span[2]) 
    return(df) 
} 

result <- getNodeSet(html.parse, "//div[@class='foo']", fun = myFunc) 

# Error in data.frame(fooname, abc, Span1 = span[1], Span2 = span[2]) : 
# arguments imply differing number of rows: 1, 0 

Вот моя попытка исправить.

myFunc <- function(x){ 
    fooname <- xpathSApply(x, "./div[@class='fooname']", fun = xmlValue) 
    abc <- xpathSApply(x, "./div[@class='abc']", fun = xmlValue) 
    span <- xpathSApply(x, "./span", fun = xmlValue) 


    dfvars <- c("fooname", "abc", "span") 

    #I think I have the same issue about assigning a variable in `apply` 
     #functions, right? 

    for(var in dfvars) { 

     if(length(eval(parse(text = var))) == 0) { 
      cat("No ", var, " value found for this group.\n") 

      #Note the "list" class: 
      cat("Class of ", var, " is: ", class(eval(parse(text = var))), "\n") 
      cat("Placing an NA.\n") 

      #This line gives an error: 
      assign(eval(parse(text = var)), as.character(NA)) 

      cat("new value of ", var, " : ", eval(parse(text = var)), "\n") 
      cat("New length of ", var, " : ", length(eval(parse(text = var))), "\n") 
      cat("New class of ", var, " : ", class(eval(parse(text = var))), "\n") 

     } 
    } 

    df <- data.frame(fooname, abc, Span1 = span[1], Span2 = span[2]) 
    return(df) 
} 

result <- getNodeSet(html.parse, "//div[@class='foo']", fun = myFunc) 

# Error in assign(eval(parse(text = var)), as.character(NA)) : 
# invalid first argument 

Обратите внимание, что в то время как здесь for цикла (или apply функцию, если я делаю это именно так) во втором вложенности слоя. В моем реальном проекте это в третьем; внешний слой открывается каждый в серии страниц. Было бы неплохо избежать перехода на третий уровень, если это возможно, но я также хочу, чтобы все было просто.

ответ

1

Вы можете определить свою собственную xpathSApply функцию, которая проверяет на list():

myXpathSApply <- function(x, ...){ 
    y <- xpathSApply(x, ...) 
    if(length(y) > 0){y}else{NA} 
} 

и использовать эту функцию, где вы используете xpathSApply:

myFunc <- function(x){ 
    fooname <- myXpathSApply(x, "./div[@class='fooname']", fun = xmlValue) 
    abc <- myXpathSApply(x, "./div[@class='abc']", fun = xmlValue) 
    span <- myXpathSApply(x, "./span", fun = xmlValue) 

    df <- data.frame(fooname, abc, Span1 = span[1], Span2 = span[2]) 
    return(df) 
} 
+0

Как представляется, работает прекрасно. Пробовал это на одной странице, теперь попробовал это на остальных. Это проблема, когда оба слоя вложенных функций заданы как 'function (x)' (и не меняют 'x' на что-то еще)? –

+0

Работал отлично для всей сети царапины! –

+0

С удовольствием ... – jdharrison

Смежные вопросы