首页 > 解决方案 > Rvest:导航 html 节点

问题描述

我正在尝试从HLTV.org抓取结果数据:我的目标是抓取每场比赛的获胜者、失败者和日期。

我已经成功地找出了每场比赛的赢家和输家——日期的结构是我苦苦挣扎的地方。每天的结果都保存在<div class="results-sublist"> 日期的值保存在嵌套在该 div 内的跨度中(注意:Chrome 告诉我它是一个 div,这是一个谎言):

 <div class="standard-headline">Results for December 28th 2020</div>

在与此跨度相同的“级别”上(即直接在“结果子列表”div 下方,我们有当天进行的每场比赛的结果。

在循环每一天之前,我试图创建一个包含一天结果的表格。

我目前的代码如下:

url <- "https://www.hltv.org/results"
s <- rvest::html_session(url)
s_tree <- xml2::read_html(s)


day_results_nodes <- s_tree %>%
 html_nodes(xpath="//div[contains(@class, 'results-sublist')]")

i <- day_results_nodes[[1]]

date <- i %>%
  html_nodes(xpath = "//span[contains(@class, 'standard-headline')]") %>%
  html_text()

winner <- i %>%
 xml2::xml_find_all("//div[contains(@class, 'team team-won')]") %>%
 rvest::html_text()

loser <- i %>%
 xml2::xml_find_all(xpath="//div[@class='team ']") %>%
 rvest::html_text()

page_results <- cbind(winner, loser, x1 = date)

page_results(实际返回)

优胜者 失败者 x1
1 超凡脱俗 林比维京人 2020 年 12 月 28 日的结果
2 胜利之击 姆巴佩克 2020 年 12 月 27 日的结果
3 X计划 Lilmix 2020 年 12 月 25 日的结果
4 布达佩斯五 Lilmix 2020 年 12 月 24 日的结果
5 X计划 印加人 2020 年 12 月 23 日的结果
... ... ... ...
100 移动之星骑士 端点 2020 年 12 月 28 日的结果

page_results(预期)

优胜者 失败者 x1
1 超凡脱俗 林比维京人 2020 年 12 月 28 日的结果
2 胜利之击 姆巴佩克 2020 年 12 月 28 日的结果
3 X计划 Lilmix 2020 年 12 月 28 日的结果

积极因素:day_results_nodes 的行为符合预期。day_results_nodes 返回 11 个 html 节点,每个节点下面的 div 数与当天的匹配数一样多。

否定:page_results 返回网页上 100 个结果的表格,而不是附加到第一个“results-sublist”div 的四个匹配项。日期列只是循环浏览网页上的 11 个可用日期,而不是与每个匹配对应的“标准标题”对应的日期(我希望在当天的“结果子列表”中的每一行上广播单个日期值)

我收到以下警告消息:

cbind(winner, loster, x1 = date) 中的警告:结果的行数不是向量长度的倍数(arg 3)

我认为这是广播没有按预期工作的副产品。

我不清楚为什么i <- day_results_nodes[[1]]似乎没有引用第一个节点(即最近一天的结果数据);打印 i 按预期返回一个带有跨度和三个类的 html 节点。这使我相信我的错误在于 xml_find_all(),尽管我不明白为什么。

标签: htmlrrvest

解决方案


xml_find_all是从根节点开始的,因为您没有将前导添加.到 xpath。我在最后显示更正。

文档中:

在此处输入图像描述

您需要每个组中正确数量的节点(例如 1 个日期与相同数量的获胜者作为失败者),以便正确填充日期回收。每个块应返回一个日期,因此您只需要html_node; 对于赢家/输家,我会切换到 css,因为这会返回相对于当前节点的正确数量的节点(来自您的索引)。使用 css 也更快。为了获得正确数量的失败者,我使用:not伪类选择器为获胜者删除具有多值类的节点;哪个有team-won课。

library(rvest)
library(magrittr)

url <- "https://www.hltv.org/results"
s <- rvest::html_session(url)
s_tree <- xml2::read_html(s)

day_results_nodes <- s_tree %>%
  html_nodes('.results-sublist')

i <- day_results_nodes[[1]]

date <- i %>%
  html_node('.standard-headline') %>%
  html_text()

winner <- i %>%
  html_nodes('.team-won') %>%
  html_text()
   
loser <- i %>%
  html_nodes('.team:not(.team-won)') %>%
  html_text()

page_results <- cbind(winner, loser, x1 = date)

路径

library(rvest)
library(magrittr)

url <- "https://www.hltv.org/results"
s <- rvest::html_session(url)
s_tree <- xml2::read_html(s)


day_results_nodes <- s_tree %>%
  html_nodes(xpath="//div[contains(@class, 'results-sublist')]")

i <- day_results_nodes[[1]]

date <- i %>%
  html_node(xpath = ".//span[contains(@class, 'standard-headline')]") %>%
  html_text()

winner <- i %>%
  xml2::xml_find_all(".//div[contains(@class, 'team team-won')]") %>%
  rvest::html_text()

loser <- i %>%
  xml2::xml_find_all(xpath=".//div[@class='team ']") %>%
  rvest::html_text()

page_results <- cbind(winner, loser, x1 = date)

page_results

推荐阅读