【发布时间】:2021-02-25 20:22:51
【问题描述】:
我正在使用rvest 编写一个数据抓取工具,如下所示:
library(tidyverse)
library(rvest)
library(magrittr)
library(dplyr)
library(tidyr)
library(data.table)
library(zoo)
targets_url <- paste0("https://247sports.com/college/ohio-state/Season/2021-Football/Targets/")
targets <- map_df(targets_url, ~.x %>% read_html %>%
html_nodes(".ri-page__star-and-score .score , .position , .meta , .ri-page__name-link") %>%
html_text() %>%
str_trim %>%
str_split(" ") %>%
matrix(ncol = 4, byrow = T) %>%
as.data.frame)
df_structure <- apply(targets,2,as.character)
df_targets <- as.data.frame(df_structure)
您会注意到它创建了一个包含四个变量和 53 行的数据框。
但是现在转到 URL 本身。您会注意到 53 行对应于某些子类别:Top Target、High Choice 和 Interested。这是一张显示示例的图片:
我要做的是创建第五列,其中包含子类别。因此,例如,属于“最高目标”的三个人将被分配另一列,将他们列为“最高目标”。然后接下来的 20 行将第五列读取为“高选择”,依此类推。我在这里的原因是因为我不知道该怎么做。更难的是,并非每一页都有相同的数字here's an example of that。您会看到,虽然上面的图片仅列出了 Top Target (3),但此页面现在有 Top Target (24)。每个页面都不同。
是否有可能改变我原来的脚本:
A) 使用我上面提到的子类别创建第五列
B) 知道什么时候应该切换到下一个子类别
C) 与每个子类别中的总人数无关
部分基于@Dave2e 答案的编辑脚本:
library(rvest)
library(dplyr)
library(stringr)
teams <- c("ohio-state","penn-state","michigan","michigan-state")
targets_url <- paste0("https://247sports.com/college/", teams, "/Season/2021-Football/Targets/")
# read the web page once! then extract the information requested
targets <- map_df(targets_url, ~.x %>% read_html %>%
html_nodes(".ri-page__star-and-score .score , .position , .meta , .ri-page__name-link") %>%
html_text() %>%
str_trim %>%
str_split(" ") %>%
matrix(ncol = 4, byrow = T) %>%
as.data.frame)
#find the headings and the players
list <- page %>% html_nodes("li.ri-page__list-item")
headers <- which(html_attr(list, "class") == "ri-page__list-item list-header")
#find the category
category <- list[headers] %>% html_node("b.name") %>% html_text()
#extract repeats from header
nrepeats<-as.integer(str_extract(category, "[0-9]+"))
categories <- rep(category, nrepeats)[1:nrow(targets)]
#create combined dataframe
answer <- cbind(categories, targets)
【问题讨论】:
标签: r web-scraping tidyverse rvest