我正在尝试使用RVest从goodreads上的多个页面中抓取数据,类似于this和this。但是,在过去的几年里,我想了解所有已成为Goodreads Choice Awards前20名的书籍的信息。以下是我到目前为止的代码:
library(tidyverse)
library(stringr)
library(rvest)
library(magrittr)
library(tibble)
startUrlGCA <- "https://www.goodreads.com/choiceawards/best-books-"
getNVotes <- function(listLink){
urls <- str_c("https://www.goodreads.com", listLink)
urls %>%
modify(read_html) %>%
modify(html_nodes, ".result") %>%
modify(html_text)
}
getLists <- function(i) {
cat(i, "\n")
url <- str_c(startUrlGCA, i)
html <- read_html(url)
category <- html %>%
html_nodes("h4") %>%
html_text() %>%
trimws()
listLinks <- html %>%
html_nodes("a") %>%
html_attr("href") %>%
discard(!str_detect(., "^/choiceawards/best-")) %>%
discard(str_detect(., "^/choiceawards/best-books-")) %>%
na.omit() %>%
unique()
nVotes <- listLinks %>%
map(getNVotes)
year <- i
tibble1 <- tibble(
year = year,
category = category,
categoryLink = listLinks,
nVotes = nVotes)
return(tibble1)
}
GCA2yrs <- c(2016:2017) %>%
map_dfr(getLists)
我遇到的最大问题是getNVotes功能。我希望它能够返回每个类别中收到的前20本书中的每一个的票数,然后我希望这些票数与哪一年以及它们所属的类别相匹配。 (最后我想要包括每本书的标题和一些关于它们的信息,但是我已经遇到了我的nVotes问题。)相反,当我运行所有这些代码时,我得到一个最终列有40个单元格的tibble ,每个都包含一个项目列表,列表中的一个项目是一个带有很多\ n和\ nvotes的字符向量,如下所示:
Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 40 obs. of 4 variables:
$ year : int 2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 ...
$ category : chr "Fiction" "Mystery & Thriller" "Historical Fiction" "Fantasy" ...
$ categoryLink: chr "/choiceawards/best-fiction-books-2016" "/choiceawards/best-mystery-thriller-books-2016" "/choiceawards/best-historical-fiction-books-2016" "/choiceawards/best-fantasy-books-2016" ...
$ nVotes :List of 40
..$ :List of 1
.. ..$ : chr "\n30,154\nvotes\n" "\n27,917\nvotes\n" "\n27,595\nvotes\n" "\n24,848\nvotes\n" ...
..$ :List of 1
.. ..$ : chr "\n42,382\nvotes\n" "\n23,038\nvotes\n" "\n21,621\nvotes\n" "\n20,475\nvotes\n" ...
..$ :List of 1
.. ..$ : chr "\n24,175\nvotes\n" "\n23,991\nvotes\n" "\n16,608\nvotes\n" "\n15,260\nvotes\n" ...
#lots more of the same below here.
我已经尝试了很多字符串函数来摆脱\ n或提取数字,并尝试使用unfst和unlist,但我在这里有点超出我的深度。
谢谢!