R:使用rvest从FIFA刮表的问题

时间:2017-11-22 05:43:20

标签: r web-scraping dplyr rvest

我正在尝试从过去30年来至少参加过一次世界杯的每支球队中获取数据。

我对如何使用R包rvest来抓取表格以及来自网络的东西的知识充其量是最基本的。

目前,我的代码看起来像

library(rvest)
library(dplyr)
fifadata <- read_html("http://www.fifa.com/fifa-tournaments/teams/association=BRA/index.html")
fifa_data_html <-  
  html_nodes(fifadata, 
         xpath='/html/body/div[1]/div[5]/div/div[4]/div/div[2]/div/div/div[1]/div/table') %>%
  html_table(header=FALSE, fill=TRUE)
fifa_data_html 

网页上的第一个表是我想要抓取的,但是当我运行上面的代码时,html_nodes()返回{xml_nodeset(0)}。

如何正确地抓取有问题的表格的任何输入将非常感激。

1 个答案:

答案 0 :(得分:0)

这是件事。这真是一团糟:

xp = paste0('//li[@class="tbl-cupname"]/',
            'div[@class="label-data"]/',
            'span[@class="text"][text()="FIFA World Cup™"]/../../',
            'following-sibling::li[@class="tbl-appearances"]/',
            'div[@class="label-data"]/',
            'span[@class="text"]')
fifadata %>% html_nodes(xpath = xp) %>% html_text %>% as.integer
# [1] 20

让我们打破逻辑。

天真的查询:

fifadata %>% html_nodes(
    xpath = '//li[@class="tbl-appearances"]/div[@class="label-data"]/span'
)

足以让我们在本页列出的四个锦标赛的每个中为我们提供四行显示次数。如果网页设计师是仁慈的,这就足够了 - 只需从你想要抓取的每个页面中选择第一个,你将拥有你想要的东西。

但这并不健全 - 每当行顺序发生变化时,或者如果您想要的行不存在,它都会给出错误的结果。

提出的查询解决了这个问题。

首先,我们确定与FIFA世界杯相关的行。基本结构是:

<li class="tbl-cupname">
  <div class="label-data">
    <span class="text"> n_appearances </span>
  </div>
</li>

我们使用class属性,因为附近还有其他lidiv我们希望确保排除这些属性。因此,我们可以选择与比赛相对应的四行(FIFA世界杯,FIFA联合会杯,FIFA女足世界杯和女子奥运会足球锦标赛):

fifadata %>% html_nodes(xpath = '//li[@class="tbl-cupname"]')

取消与你的追求无关的三场比赛需要<span>元素的条件,因此第一部分的其余部分:

xp_part_1 = paste0('//li[@class="tbl-cupname"]/',
                   'div[@class="label-data"]/',
                   'span[@class="text"][text()="FIFA World Cup™"]')
fifadata %>% html_nodes(xpath = xp_part_1)

这会选择锦标赛,但是,我们需要后续 li,其中包含数字的外观。我们在这里讨论的核心结构是:

<li class="tbl-cupname"> </li>
<li class="tbl-appearances"> </li>

xpath的第1部分已将我们导航到此li下方的两个级别,但是,我们需要使用..“提升”节点(这与cd ..完全相同Linux终端上升到一个水平,所以希望这让人联想到。)

然后我们使用following-sibling语法选择与当前节点处于同一级别的节点,但随后会出现。

一旦我们回到与命名锦标赛的li相同的级别,我们可以继续使用“天真”查询来深入查看出场次数。