В настоящее время я просматриваю веб-сайт IMDB, чтобы извлечь данные о фильмах.
Хотелось бы узнать, как бы вы решили эту проблему.
library(tidyverse)
library(data.table)
library(rvest)
library(janitor)
#top rated movies website
url <- 'https://www.imdb.com/chart/top/?ref_=nv_mv_250'
# extract the title of the movies using rvest
titles <- url %>%
read_html() %>%
html_nodes(' .titleColumn a') %>%
html_text() %>%
as.data.table() %>%
setnames(. ,old = colnames(.), new='title')
# extract links to each of the titles, this will be the reference
links <- url %>%
read_html() %>%
html_nodes('.titleColumn a') %>%
html_attr('href') %>%
as.data.table() %>%
setnames(. ,old = colnames(.), new='links')
# creating a DT with the data
movies <- cbind(titles,links)
У меня будут фильмы DT с заголовком и ссылками в виде столбцов.
Теперь я хочу извлечь дополнительные данные о каждом фильме, используя ссылки
Я продолжу использовать в качестве примера первую строку.
#the first link in movies
link <- 'https://www.imdb.com/title/tt0111161/?pf_rd_m=A2FGELUUNOQJNL&pf_rd_p=e31d89dd-322d-4646-8962-327b42fe94b1&pf_rd_r=NJ52X0MM1V9FKSPBT46G&pf_rd_s=center-1&pf_rd_t=15506&pf_rd_i=top&ref_=chttp_tt_1'
# selector for budget data (this will not change)
select <- '.txt-block:nth-child(15) , .txt-block:nth-child(14) , #titleDetails .txt-block:nth-child(13) , #titleDetails .txt-block:nth-child(12)'
# get budget data
budget <- link %>%
read_html() %>%
html_nodes(select) %>%
html_text() %>%
gsub('\\n','',.) %>%
str_split(.,'\\:')%>%
as.data.table() %>%
janitor::row_to_names(row_number = 1) %>%
setnames(.,old=colnames(.),new= tolower(gsub(' ','_' , str_trim(colnames(.)))))
budget[,(colnames(budget))] <- lapply(budget,function(x) str_extract_all(x, "(\\$) *([0-9,]+)"))
Теперь у меня есть таблица размером 1х4 с бюджетной информацией.
Я хотел бы извлечь данные для каждой ссылки фильмов и объединить их в DT, чтобы получить окончательное DT с 6 столбцами; "название", "ссылка" + четыре бюджетные переменные. Я пытался создать функцию, которая включает в себя код для получения данных бюджета, используя ссылку каждой строки в качестве параметра и используя «lapply», я не думаю, что это правильный подход.
Я хотел бы увидеть, есть ли у вас эффективное решение этой проблемы.
Большое спасибо за Вашу помощь.
1 ответ
Думаю, это решит вашу проблему:
# selector for budget data (this will not change)
select <- '.txt-block:nth-child(15) , .txt-block:nth-child(14) , #titleDetails .txt-block:nth-child(13) , #titleDetails .txt-block:nth-child(12)'
# get budget data
## As function
get_budget = function(link,select){
budget <- link %>%
read_html() %>%
html_nodes(select) %>%
html_text() %>%
gsub('\\n','',.) %>%
str_split(.,'\\:')%>%
as.data.table() %>%
janitor::row_to_names(row_number = 1) %>%
setnames(.,old=colnames(.),new= tolower(gsub(' ','_' , str_trim(colnames(.)))))
budget[,(colnames(budget))] <- lapply(budget,function(x) str_extract_all(x, "(\\$) *([0-9,]+)"))
return(budget)
}
#As your code is slow I'll subset movies to have 10 rows:
movies = movies[1:10,]
tmp =
lapply(movies[, links], function(x)
get_budget(link = paste0("https://www.imdb.com/",x),select=select )) %>%
rbindlist(., fill = T)
movies = cbind(movies, tmp)
И ваш результат будет выглядеть так: movies_result
Наконец, я думаю, этот небольшой совет сделает ваш код круче:
setnames
не требует.
отmagrittr
; он автоматически понимает ваш тип кода.- По возможности избегайте использования
setnames(. ,old = colnames(.), new='links')
. В вашем случае просто необходимоsetnames('links')
, так как вы переименовываете все свои переменные. setnames(dt,old = oldnames, new=newnames)
необходимо только тогда, когда oldnames не равно name (dt).- Поскольку
DT
- еще одна популярная библиотекаR
, совершенно не связанная сdata.table
, я думаю, что лучше ссылаться на data.table как наdata.table
.
Похожие вопросы
Новые вопросы
r
R — это бесплатный язык программирования с открытым исходным кодом и программная среда для статистических вычислений, биоинформатики, визуализации и общих вычислений. Пожалуйста, используйте минимально воспроизводимые примеры, которые другие могут запустить с помощью копирования и вставки. Показать желаемый результат полностью. Используйте dput() для данных и укажите все небазовые пакеты с помощью library(). Не вставляйте изображения для данных или кода, вместо этого используйте блоки кода с отступом. Для вопросов по статистике используйте https://stats.stackexchange.com.