html - 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(),尽管我不明白为什么。
解决方案
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
推荐阅读
- python - Python 包文件夹结构
- python - 格式化整个excel工作表 - Python
- oracle - Oracle - 从层次结构表中结束子节点
- python-3.x - 用于循环的 Django cms 模板在渲染期间会自行中断
- javascript - 无法让 api 数组从数组中输出 1 个第一个元素,它只在 jquery/javascript 中一次输出所有元素
- sql - 通过 VBA 连接执行长查询
- firebase - 如何使用 Flutter 从 Firestore 中的 ListView 获得无限滚动
- c++ - 带有 Poco::Net::TCPServer 的 Unix 域套接字
- java - BufferedImageOp 内核卷积没有做任何事情
- r - 避免在 Plotly (R) 中显示日语字符串的 JSON 错误/一次在一个变量上运行函数