使用 XML 包将 html 表抓取到 R 数据帧中
Posted
技术标签:
【中文标题】使用 XML 包将 html 表抓取到 R 数据帧中【英文标题】:Scraping html tables into R data frames using the XML package 【发布时间】:2010-11-26 14:26:41 【问题描述】:如何使用 XML 包抓取 html 表?
以Brazilian soccer team 上的这个***页面为例。我想在 R 中阅读它并获取“巴西与国际足联认可的球队进行的所有比赛的列表”表作为 data.frame。我该怎么做?
【问题讨论】:
要制定 xpath 选择器,请查看 selectorgadget.com/ - 这太棒了 【参考方案1】:…或更短的尝试:
library(XML)
library(RCurl)
library(rlist)
theurl <- getURL("https://en.wikipedia.org/wiki/Brazil_national_football_team",.opts = list(ssl.verifypeer = FALSE) )
tables <- readHTMLTable(theurl)
tables <- list.clean(tables, fun = is.null, recursive = FALSE)
n.rows <- unlist(lapply(tables, function(t) dim(t)[1]))
选中的表格是页面上最长的表格
tables[[which.max(n.rows)]]
【讨论】:
readHTMLTable 帮助还提供了一个使用 htmlParse()、getNodeSet()、textConnection() 和 read.table() 从 HTML PRE 元素中读取纯文本表格的示例【参考方案2】:library(RCurl)
library(XML)
# Download page using RCurl
# You may need to set proxy details, etc., in the call to getURL
theurl <- "http://en.wikipedia.org/wiki/Brazil_national_football_team"
webpage <- getURL(theurl)
# Process escape characters
webpage <- readLines(tc <- textConnection(webpage)); close(tc)
# Parse the html tree, ignoring errors on the page
pagetree <- htmlTreeParse(webpage, error=function(...))
# Navigate your way through the tree. It may be possible to do this more efficiently using getNodeSet
body <- pagetree$children$html$children$body
divbodyContent <- body$children$div$children[[1]]$children$div$children[[4]]
tables <- divbodyContent$children[names(divbodyContent)=="table"]
#In this case, the required table is the only one with class "wikitable sortable"
tableclasses <- sapply(tables, function(x) x$attributes["class"])
thetable <- tables[which(tableclasses=="wikitable sortable")]$table
#Get columns headers
headers <- thetable$children[[1]]$children
columnnames <- unname(sapply(headers, function(x) x$children$text$value))
# Get rows from table
content <- c()
for(i in 2:length(thetable$children))
tablerow <- thetable$children[[i]]$children
opponent <- tablerow[[1]]$children[[2]]$children$text$value
others <- unname(sapply(tablerow[-1], function(x) x$children$text$value))
content <- rbind(content, c(opponent, others))
# Convert to data frame
colnames(content) <- columnnames
as.data.frame(content)
编辑添加:
样本输出
Opponent Played Won Drawn Lost Goals for Goals against % Won
1 Argentina 94 36 24 34 148 150 38.3%
2 Paraguay 72 44 17 11 160 61 61.1%
3 Uruguay 72 33 19 20 127 93 45.8%
...
【讨论】:
对于有幸找到这篇文章的任何其他人,除非用户添加他们的“用户代理”信息,否则此脚本可能不会执行,如另一篇有用的帖子中所述:***.com/questions/9056705/… 【参考方案3】:另一个使用 Xpath 的选项。
library(RCurl)
library(XML)
theurl <- "http://en.wikipedia.org/wiki/Brazil_national_football_team"
webpage <- getURL(theurl)
webpage <- readLines(tc <- textConnection(webpage)); close(tc)
pagetree <- htmlTreeParse(webpage, error=function(...), useInternalNodes = TRUE)
# Extract table header and contents
tablehead <- xpathSApply(pagetree, "//*/table[@class='wikitable sortable']/tr/th", xmlValue)
results <- xpathSApply(pagetree, "//*/table[@class='wikitable sortable']/tr/td", xmlValue)
# Convert character vector to dataframe
content <- as.data.frame(matrix(results, ncol = 8, byrow = TRUE))
# Clean up the results
content[,1] <- gsub("Â ", "", content[,1])
tablehead <- gsub("Â ", "", tablehead)
names(content) <- tablehead
产生这个结果
> head(content)
Opponent Played Won Drawn Lost Goals for Goals against % Won
1 Argentina 94 36 24 34 148 150 38.3%
2 Paraguay 72 44 17 11 160 61 61.1%
3 Uruguay 72 33 19 20 127 93 45.8%
4 Chile 64 45 12 7 147 53 70.3%
5 Peru 39 27 9 3 83 27 69.2%
6 Mexico 36 21 6 9 69 34 58.3%
【讨论】:
非常适合使用 xpath。次要点:您可以通过将 //*/ 更改为 // 来稍微简化路径参数,例如"//table[@class='wikitable sortable']/tr/th" 我收到一条错误消息“脚本应使用带有联系信息的用户代理字符串,否则它们可能会在不通知的情况下被 IP 阻止。” [2] " 有没有办法实现这个方法? 选项(RCurlOptions = list(useragent = "zzzz"))。另请参阅omegahat.org/RCurl/FAQ.html“运行时”部分以了解其他替代方案和讨论。【参考方案4】:rvest
和 xml2
是另一个流行的 html 网页解析包。
library(rvest)
theurl <- "http://en.wikipedia.org/wiki/Brazil_national_football_team"
file<-read_html(theurl)
tables<-html_nodes(file, "table")
table1 <- html_table(tables[4], fill = TRUE)
该语法比xml
包更易于使用,并且对于大多数网页,该包提供了所需的所有选项。
【讨论】:
read_html 给了我错误“'file:///Users/grieb/Auswertungen/tetyana-snp-2016/data/snp-nexus/15/SNP%20Annotation%20Tool.html'当前工作目录中不存在('/Users/grieb/Auswertungen/tetyana-snp-2016/code')。”以上是关于使用 XML 包将 html 表抓取到 R 数据帧中的主要内容,如果未能解决你的问题,请参考以下文章
使用 XML / RCurl R 包解析 HTML 表,而不使用 readHTMLTable 函数
当从r输出到excel工作表(使用xlsx包)时,数据框列标题中的问号为什么显示为句点?