2.12中的XML包错误,但不是2.10

时间:2011-02-03 02:31:00

标签: xml r web-scraping

我正在使用R中的XML包来从页面中读取HTML表。在2.12.1中,我收到以下错误:

Error in names(ans) = header : 
  'names' attribute [24] must be the same length as the vector [19]

但是,当我在2.10中运行相同的代码片段时,没有错误,一切都解析(几乎)正常。我说几乎是因为列名取自表的第一行,但我可以绕过它。

这是我的代码:

## load the libraries
library(XML)

## set the season
SEASON <- "2011"

## create the URL
URL <- paste("http://www.hockey-reference.com/leagues/NHL_", SEASON, "_goalies.html", sep="")

## grab the page -- the table is parsed nicely -- why work 2.10, but not 2.12.1?
tables <- readHTMLTable(URL)

非常感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:1)

由于转移到v2.12.1,我不确定是否会出现此问题。我在2.12.1上尝试过它并得到同样的错误。

但是,也可能由于HTML中的某些内容发生更改而发生错误。我查看了该页面上的HTML源代码,并且表格的形成方式并不像人们希望的那样好。 HTML表有两个问题:1)第一个标题行包含合并列,2)标题行重复。

这是导致代码返回错误的第一个问题。数据行的长度为19,但是标题包括两行,一行长度为19,长度为一行,即总共24行。正是这种差异引发了你的错误。

我无法使用readHTMLTable()函数抓取此页面。但是我的解决方案是使用scrapeR和XML中的工具:

# load the libraries
library(XML)
library(scrapeR)
library(plyr)
library(stringr)

# scrape and parse page
page <- scrape(url=URL, parse=TRUE)
raw <- xpathSApply(page[[1]], "//table//tr", xmlValue)
# split strings at each line break
rows <- strsplit(raw, "\n")
# now check for longest row length, and discard all short rows
rowlength <- (laply(rows, length))
rows <- rows[rowlength==max(rowlength)]
# unlist each row
rows <- laply(rows, function(x)unlist(x))
# trim white space
rows <- aaply(rows, c(1,2), str_trim)
# convert to data frame
df <- as.data.frame(rows, stringsAsFactors = FALSE)
# read names from first row
names(df) <- laply(df[1, ], str_trim)
# remove all rows without a numerix index
df <- df[which(!is.na(as.numeric(df$Rk))), ]
df

代码有点混乱,表格不干净,因为所有数据都是字符向量,而不是数字。

但至少这意味着您拥有可以进一步处理的格式的数据。