【问题标题】:scrape HTML table with multiple pages using R使用 R 抓取具有多个页面的 HTML 表
【发布时间】:2014-04-22 23:52:31
【问题描述】:

我正在尝试通过从网络上抓取来制作数据框。但是有多个页面组成了我要抓取的表格。相同的链接,但页面不同。

对于第一页,我会这样刮:

library(XML)
CB.13<- "http://www.nfl.com/stats/categorystats?tabSeq=1&season=2013&seasonType=REG&experience=&Submit=Go&archive=false&conference=null&d-447263-p=1&statisticPositionCategory=DEFENSIVE_BACK&qualified=true"
CB.13<- readHTMLTable(CB.13, header=FALSE)
cornerback.function<- function(CB.13){
  first<- "1"
  last<- "1"
  for (i in 1:length(CB.13)){
    lastrow<- nrow(CB.13[[i]])
    lastcol<- ncol(CB.13[[i]])
    if(as.numeric(CB.13[[i]] [1,1]) ==first & as.numeric(CB.13[[i]] [lastrow, lastcol]) ==last) {
      tab <- i
    }
  }
}
cornerback.function(CB.13)
cornerbacks.2013<- CB.13[[tab]]
cb.names<- c("Rk", "name", "Team", "Pos", "Comb", "Total", "Ast", "Sck", "SFTY", "PDef", "Int", "TDs", "Yds", "Lng", "FF", "Rec", "TD")
names(cornerbacks.2013)<- cb.names

我需要这样做多年,所有页面都有多个页面 - 那么有没有更快的方法来获取数据的所有页面,而不必为表格的每个单独页面执行此操作并合并它们?下一个链接是http://www.nfl.com/stats/categorystats?tabSeq=1&season=2013&seasonType=REG&Submit=Go&experience=&archive=false&conference=null&d-447263-p=2&statisticPositionCategory=DEFENSIVE_BACK&qualified=true

今年有 8 页——也许是一个 for 循环来循环页面?

【问题讨论】:

  • 好吧,我做到了……你对这个有什么建议吗

标签: xml r web-scraping


【解决方案1】:

您可以使用paste0 动态创建网址,因为它们略有不同。对于某一年,您只更改页码。你会得到一个像这样的 url 结构:

url <- paste0(url1,year,url2,page,url3) ## you change page or year or both

您可以创建一个函数来遍历不同的页面,并返回一个表格。然后你可以使用经典的do.call(rbind,..)绑定它们:

library(XML)
url1 <- "http://www.nfl.com/stats/categorystats?tabSeq=1&season="
year <- 2013
url2 <- "&seasonType=REG&experience=&Submit=Go&archive=false&conference=null&d-447263-p="
page <- 1
url3 <- "&statisticPositionCategory=DEFENSIVE_BACK&qualified=true"

getTable <- 
  function(page=1,year=2013){
    url <- paste0(url1,year,url2,page,url3)
    tab = readHTMLTable(url,header=FALSE) ## see comment !!
    tab$result
}
## this will merge all tables in a single big table
do.call(rbind,lapply(seq_len(8),getTable,year=2013))

一般方法

一般的方法是使用一些 xpath 标记废弃下一页 url 并循环直到没有任何新的下一页。这可能更难做到,但它是最干净的解决方案。

getNext <- 
function(url=url_base){
  doc <- htmlParse(url)
  XPATH_NEXT = "//*[@class='linkNavigation floatRight']/*[contains(., 'next')]"
  next_page <- unique(xpathSApply(doc,XPATH_NEXT,xmlGetAttr,'href'))
  if(length(next_page)>0)
    paste0("http://www.nfl.com",next_page)
  else ''
}
## url_base is your first  url
res <- list()
while(TRUE){
  tab = readHTMLTable(url_base,header=FALSE)
  res <- rbind(res,tab$result)
  url_base <- getNext(url_base)
  if (nchar(url_base)==0)
    break
}

【讨论】:

  • 您可能希望将header = FALSE 添加到readHTMLTable。由于某种原因,没有它就不会返回第一行,这是一个问题。信息是here。非常好,否则(+1)。
  • @RichardScriven 我编辑我的答案以添加您的评论和另一个更通用的抓取解决方案。
猜你喜欢
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-18
  • 2022-01-03
  • 1970-01-01
  • 2016-08-09
相关资源
最近更新 更多