在 R 中使用 Rvest 从网站中提取 <p> 和 <span> 元素时卡住了
Stuck while using Rvest in R to extract <p> and <span> elements from a website
我一直在使用 Rvest 尝试构建 NBA 仪表板,在 R 中进行一些网络抓取。在过去,我已经能够很容易地从 basketball-reference.com 中抓取时间表,因为它的网络结构设置为 HTML table。最近发现有一个NBA交易页面,名字叫
https://www.basketball-reference.com/leagues/NBA_2020_transactions.html,我想从中抓取数据并将其放在我的仪表板上。
下面是网页的图片,我需要的数据,以及它的页面结构。可以看到日期存储在 <.span> 对象中,并且在该特定日期发生的每个事件都有 <.p> 对象。我基本上只想将所有这些数据提取到 R 中的 2 个主要列中,将跨度数据转换为日期列,将 p 数据转换为事件列。
下面是我目前得到的一些代码,读取 url,将其转换为可读的 html,然后找到我需要的数据。我缺少几个步骤来获取我之前提到的格式的数据,但我不知道它们是什么。我可以通过使用 separate & gsub 手动操作数据的艰难方式来做到这一点,但这感觉是一个我希望避免的非常乏味的过程。
library(tidyverse)
library(rvest)
library(xml2)
url <- paste0('https://www.basketball-reference.com/leagues/NBA_2020_transactions.html')
webpage <- read_html(url)
# this returns a nested list of the data i want, but i dont know what to do from there
prac5 <- webpage %>%
html_nodes("div#content > ul > li")
# this returns a data frame of the data i want but it's all jumbled together
prac6 <- webpage %>%
html_nodes("div#content > ul > li") %>%
html_text() %>%
as.data.frame()
昨天,我发现了一个代码片段,有人试图做类似的事情,他们使用了下面的方法,但我无法正确地调整它以适应我想要的。
bb <- html_nodes(webpage, "div#content > ul > li") %>%
map_df(~{
data_frame(
date = html_node(.x, "span") %>% html_text(trim=TRUE),
event = html_nodes(.x, "ul > li") %>% html_text(trim=TRUE)
)
})
如果有人能提供任何帮助或见解,我将不胜感激!
如果像在 prac6
中那样删除所有 HTML 标签,事情会变得一团糟,所以您可以在这样做之前停下来:
prac6 <- webpage %>%
html_nodes("div#content > ul > li")
然后将 <span>
和 <p>
内容解析到新的 dataframe/tibble 中的单独列中。由于每个日期可以包含多个事件,我们为每个日期创建一个新的 df,然后将它们连接在一起:
prac7 <- lapply(prac6, function(node) {
tibble(date = html_node(node, "span") %>% html_text(trim=TRUE),
event = html_nodes(node, "p") %>% html_text(trim=TRUE))
})
prac8 <- bind_rows(prac7)
这会产生:
# A tibble: 1,796 x 2
date event
<chr> <chr>
1 November 11, 2020 The Oklahoma City Thunder hired Mark Daigneault as Head Coach.
2 October 31, 2020 The Houston Rockets hired Stephen Silas as Head Coach.
3 October 22, 2020 The New Orleans Pelicans hired Stan Van Gundy as Head Coach.
4 October 20, 2020 The Indiana Pacers hired Nate Bjorkgren as Head Coach.
5 October 20, 2020 The Los Angeles Clippers hired Tyronn Lue as Head Coach.
6 October 15, 2020 Daryl Morey resigns as GM for Houston Rockets.
7 October 15, 2020 The Houston Rockets appointed Rafael Stone as GM.
8 October 3, 2020 The Philadelphia 76ers hired Doc Rivers as Head Coach.
9 September 28, 2020 The Los Angeles Clippers fired Doc Rivers as Head Coach.
10 September 22, 2020 The Chicago Bulls hired Billy Donovan as Head Coach.
# ... with 1,786 more rows
...
你很接近,你需要html_nodes(.x, "p")
这是一个使用 lapply
而不是 map
的解决方案:
prac5 <- webpage %>%
html_nodes("div#content > ul > li")
dfs <- lapply(prac5, function(node) {
date = html_node(node, "span") %>% html_text(trim=TRUE)
event = html_nodes(node, "p") %>% html_text(trim=TRUE)
data.frame(date, event)
})
answer <- bind_rows(dfs)
我一直在使用 Rvest 尝试构建 NBA 仪表板,在 R 中进行一些网络抓取。在过去,我已经能够很容易地从 basketball-reference.com 中抓取时间表,因为它的网络结构设置为 HTML table。最近发现有一个NBA交易页面,名字叫
https://www.basketball-reference.com/leagues/NBA_2020_transactions.html,我想从中抓取数据并将其放在我的仪表板上。
下面是网页的图片,我需要的数据,以及它的页面结构。可以看到日期存储在 <.span> 对象中,并且在该特定日期发生的每个事件都有 <.p> 对象。我基本上只想将所有这些数据提取到 R 中的 2 个主要列中,将跨度数据转换为日期列,将 p 数据转换为事件列。
下面是我目前得到的一些代码,读取 url,将其转换为可读的 html,然后找到我需要的数据。我缺少几个步骤来获取我之前提到的格式的数据,但我不知道它们是什么。我可以通过使用 separate & gsub 手动操作数据的艰难方式来做到这一点,但这感觉是一个我希望避免的非常乏味的过程。
library(tidyverse)
library(rvest)
library(xml2)
url <- paste0('https://www.basketball-reference.com/leagues/NBA_2020_transactions.html')
webpage <- read_html(url)
# this returns a nested list of the data i want, but i dont know what to do from there
prac5 <- webpage %>%
html_nodes("div#content > ul > li")
# this returns a data frame of the data i want but it's all jumbled together
prac6 <- webpage %>%
html_nodes("div#content > ul > li") %>%
html_text() %>%
as.data.frame()
昨天,我发现了一个代码片段,有人试图做类似的事情,他们使用了下面的方法,但我无法正确地调整它以适应我想要的。
bb <- html_nodes(webpage, "div#content > ul > li") %>%
map_df(~{
data_frame(
date = html_node(.x, "span") %>% html_text(trim=TRUE),
event = html_nodes(.x, "ul > li") %>% html_text(trim=TRUE)
)
})
如果有人能提供任何帮助或见解,我将不胜感激!
如果像在 prac6
中那样删除所有 HTML 标签,事情会变得一团糟,所以您可以在这样做之前停下来:
prac6 <- webpage %>%
html_nodes("div#content > ul > li")
然后将 <span>
和 <p>
内容解析到新的 dataframe/tibble 中的单独列中。由于每个日期可以包含多个事件,我们为每个日期创建一个新的 df,然后将它们连接在一起:
prac7 <- lapply(prac6, function(node) {
tibble(date = html_node(node, "span") %>% html_text(trim=TRUE),
event = html_nodes(node, "p") %>% html_text(trim=TRUE))
})
prac8 <- bind_rows(prac7)
这会产生:
# A tibble: 1,796 x 2
date event
<chr> <chr>
1 November 11, 2020 The Oklahoma City Thunder hired Mark Daigneault as Head Coach.
2 October 31, 2020 The Houston Rockets hired Stephen Silas as Head Coach.
3 October 22, 2020 The New Orleans Pelicans hired Stan Van Gundy as Head Coach.
4 October 20, 2020 The Indiana Pacers hired Nate Bjorkgren as Head Coach.
5 October 20, 2020 The Los Angeles Clippers hired Tyronn Lue as Head Coach.
6 October 15, 2020 Daryl Morey resigns as GM for Houston Rockets.
7 October 15, 2020 The Houston Rockets appointed Rafael Stone as GM.
8 October 3, 2020 The Philadelphia 76ers hired Doc Rivers as Head Coach.
9 September 28, 2020 The Los Angeles Clippers fired Doc Rivers as Head Coach.
10 September 22, 2020 The Chicago Bulls hired Billy Donovan as Head Coach.
# ... with 1,786 more rows
...
你很接近,你需要html_nodes(.x, "p")
这是一个使用 lapply
而不是 map
的解决方案:
prac5 <- webpage %>%
html_nodes("div#content > ul > li")
dfs <- lapply(prac5, function(node) {
date = html_node(node, "span") %>% html_text(trim=TRUE)
event = html_nodes(node, "p") %>% html_text(trim=TRUE)
data.frame(date, event)
})
answer <- bind_rows(dfs)