从维基百科的某个部分中抓取 table

Scraping a table from a section in Wikipedia

我正在尝试想出一个可靠的方法来获得每个赛季 NFL 球队的最终排名;奇妙的是,a Wikipedia page 包含指向所有这些信息的链接。

不幸的是,how/where 存储的最终排名 table 中存在很多不一致(考虑到联赛结构的演变,这可能是意料之中的)。

可取之处应该相关的table总是在含有"Standings".

的部分中

有什么方法可以 grep 部分名称并只提取那里的 table 节点吗?

这里有一些示例页面来演示结构:

总结:

# season |                                   xpath |                                          css
-------------------------------------------------------------------------------------------------
#   1922 |     //*[@id="mw-content-text"]/table[2] |           #mw-content-text > table.wikitable
#   1950 | //*[@id="mw-content-text"]/div[2]/table | #mw-content-text > div:nth-child(20) > table
#        | //*[@id="mw-content-text"]/div[3]/table | #mw-content-text > div:nth-child(21) > table
#   2000 | //*[@id="mw-content-text"]/div[2]/table | #mw-content-text > div:nth-child(16) > table
#        | //*[@id="mw-content-text"]/div[3]/table | #mw-content-text > div:nth-child(17) > table

抓取,例如 1922 很容易:

output <- read_html("https://en.wikipedia.org/wiki/1922_NFL_season") %>%
  html_node(xpath = '//*[@id="mw-content-text"]/table[2]') %>% whatever_else(...)

但是我没有看到任何可以在 xpath 中使用的模式,也没有看到可以用来概括它的 CSS 选择器,所以我不必进行 80 次单独的抓取练习。

是否有任何可靠的方法来尝试抓取所有这些 table,特别是考虑到所有 table 都位于一个标题下方的关键洞察力 return TRUE 来自 grepl("standing", tolower(section_title))

您可以通过使用 lapply 循环 URL 并使用精心选择的 XPath 选择器提取表格来一次抓取所有内容:

library(rvest)

lapply(paste0('https://en.wikipedia.org/wiki/', 1920:2015, '_NFL_season'), 
       function(url){ 
           url %>% read_html() %>% 
               html_nodes(xpath = '//span[contains(@id, "tandings")]/following::*[@title="Winning percentage" or text()="PCT"]/ancestor::table') %>% 
               html_table(fill = TRUE)
       })

XPath 选择器寻找

  • //span[contains(@id, "tandings")]
    • 所有 span 中包含 idtandings(例如 "Standings"、"Final standings")
  • /following::*[@title="Winning percentage" or text()="PCT"]
    • 在 HTML 之后有一个节点
      • "Winning Percentage"
      • title 属性
      • 或包含"PCT"
  • /ancestor::table
    • 并选择 table 从该节点开始在树上的节点。