html - 如何解析具有嵌套结构的html文件?

标签 html r html-parsing

使用 R 和 XML 包,我一直在尝试从结构类似于此的 html 文件中提取地址:

<!DOCTYPE html>
  <body>
    <div class='entry'>
      <span class='name'>Marcus Smith</span>
      <span class='town'>New York</span>
      <span class='phone'>123456789</span>
    </div>
    <div class='entry'>
      <span class='name'>Henry Higgins</span>
      <span class='town'>London</span>
    </div>
    <div class='entry'>
      <span class='name'>Paul Miller</span>
      <span class='town'>Boston</span>
      <span class='phone'>987654321</span>
    </div>
  </body>
</html>

我先做以下事情

library(XML)
html <- htmlTreeParse("test.html", useInternalNodes = TRUE)
root <- xmlRoot(html)

现在,我可以用这个得到所有的名字:

xpathSApply(root, "//span[@class='name']", xmlValue)
## [1] "Marcus Smith"  "Henry Higgins" "Paul Miller"

现在的问题是某些元素并未出现在所有地址中。在示例中,这是电话号码:

xpathSApply(root, "//span[@class='phone']", xmlValue)
## [1] "123456789" "987654321"

如果我这样做,我就无法将电话号码分配给正确的人。因此,我尝试首先提取整个地址簿条目,如下所示:

divs <- getNodeSet(root, "//div[@class='entry']")
divs[[1]]
## <div class="entry">
##   <span class="name">Marcus Smith</span>
##   <span class="town">New York</span>
##   <span class="phone">123456789</span>
## </div> 

从输出中我认为我已经达到了我的目标并且我可以获得例如与第一个条目对应的名称如下:

xpathSApply(divs[[1]], "//span[@class='name']", xmlValue)
## [1] "Marcus Smith"  "Henry Higgins" "Paul Miller" 

但是即使 divs[[1]] 的输出只显示了 Marcus Smith 的数据,我还是得到了所有三个名字。

这是为什么?我必须做什么,以这样一种方式提取地址数据,我知道 nametownphone 的哪些值永远在一起?

最佳答案

如果每个条目的项目数量未知,您可以将 dplyr::bind_rowsdata.table::rbindlistrvest 结合使用如下:

require(rvest)
require(dplyr)
# Little helper-function to extract all children and set Names
extract_info <- function(node){
  child <- html_children(node)
  as.list(setNames(child %>% html_text(), child %>% html_attr("class")))
}

doc <- read_html(txt)
doc %>% html_nodes(".entry") %>% lapply(extract_info) %>% bind_rows

给你:

           name     town     phone
          (chr)    (chr)     (chr)
1  Marcus Smith New York 123456789
2 Henry Higgins   London        NA
3   Paul Miller   Boston 987654321

或者使用 rbindlist(fill=TRUE) 而不是 bind_rows 从而生成 data.table。或者使用 purrr 使用 map_df(as.list) 代替。

关于html - 如何解析具有嵌套结构的html文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39047835/

相关文章:

html - 如何水平居中元素?

javascript - 在 javascript 中,如何删除之前单击的同级 div,以便一次只显示一个答案?

r - 由 'ggpair' 和 'ggplot' 并排生成的图

r - 在 R 中取消引用函数内部的参数

javascript - Jquery 在 html 页面上查找名称并添​​加超链接

java - 通过java获取网页

html - 为什么我得到 undefined method `each' for nil :NilClass in Rails?

html - 在 src 中显示带有通配符的图像

r - 从列中获取一些值以使多个新列与 R 中的 id 列匹配

python - 如何在 Beautiful Soup 中将网页抓取的输出写入列而不是行