Парсинг Топ-100 фильмов IMDb 2015–2020 (R)
Table Of Content
- let's see the data
- since there are still many "\n" characters, let's remove them first
- let's also remove any empty spaces
- since one movie can have multiple genres, we only categorize each movie
- based on the first genre description
- convert the genre data from text to factor
- get the rating text data
- convert it to numeric
- get the gross data
- remove the "M" and "$" characters
- check the length of gross_data, as not all movies have gross data
- gather the data into a dataframe
- Парсинг веб-страниц с использованием R
- RPubs
- Описание
Привет, друзья! В этом руководстве я попробую получить данные о 100 самых популярных фильмах с 2015 по 2020 годы с IMDb. Я собираюсь получить информацию о рейтинге фильма, жанре и кассовых сборах.
Вот задачи, которые я собираюсь решить.
Прежде чем начать веб-парсинг в R, я подготовлю необходимые пакеты для решения задачи, включая:
library(xml2)
library(rvest)
library(ggplot2)
library(gridExtra)
Убедитесь, что вы установили эти пакеты перед их вызовом. Если нет, вы можете установить их с помощью следующей команды:
install.packages()
Сначала я считываю содержимое файла .html. Это общий метод чтения всего текста. Для более точного контроля я использую пакеты xml2 и rvest, которые я уже вызвал ранее. Ниже приведен пример чтения для 2015 года. То же самое делается для следующих лет до 2020 года. Например, для 2020 года я просто изменяю синтаксис с «date = 2015,2015» на «date = 2020,2020».
#==========2015=============#
address1 <- '[https://www.imdb.com/search/title/?count=100&release_date=2015,2015&title_type=feature'](https://www.imdb.com/search/title/?count=100&release_date=2015%2C2015&title_type=feature%27)
webpage1 <- read_html(address1)
Затем я парсю жанр с веб-сайта IMDb с помощью расширения SelectorGadget в поисковом движке. Это делается для определения местоположения жанра на веб-сайте IMDb.
Затем я вставляю результат в следующий синтаксис:
genre_data_webpage1 <- html_nodes(webpage1,'.genre')
genre_data_webpage1# we take the genre text data
genre_data1 <- html_text(genre_data_webpage1)
# let's see the data
genre_data1
# since there are still many "\n" characters, let's remove them first
genre_data1<-gsub("\n","",genre_data1)
# let's also remove any empty spaces
genre_data1<-gsub(" ","",genre_data1)
# since one movie can have multiple genres, we only categorize each movie
# based on the first genre description
genre_data1<-gsub(",.*","",genre_data1)
genre_data1
# convert the genre data from text to factor
genre_data1<-as.factor(genre_data1)
genre_data1
Тогда результат будет выглядеть следующим образом:
Затем я делаю то же самое, чтобы увидеть позицию рейтинга, используя расширение SelectorGadget. Не забудьте убедиться, что длина данных составляет 100 фильмов без пропусков. Вот синтаксис для получения рейтинга фильма:
rating_data_webpage1 <- html_nodes(webpage1,'.ratings-imdb-rating strong')
rating_data_webpage1
# get the rating text data
rating_data1 <- html_text(rating_data_webpage1)
rating_data1
# convert it to numeric
rating_data1 <-as.numeric(rating_data1)
length(rating_data1)
rating_data1
Тогда результат будет выглядеть следующим образом:
Затем я парсю данные о кассовых сборах. Когда я проверил длину данных, оказалось, что нет 100 данных/фильмов. Поэтому я ручным образом заполняю пропущенные значения в объекте gross_data. Такой подход используется для объектов, которые имеют пропущенные значения или неполные данные.
# get the gross data
gross_data_webpage1 <- html_nodes(webpage1,'.ghost~ .text-muted+ span')
gross_data1 <- html_text(gross_data_webpage1)
gross_data1
# remove the "M" and "$" characters
gross_data1<-gsub("M","",gross_data1)
gross_data1<-substring(gross_data1,2,6)
gross_data1
# check the length of gross_data, as not all movies have gross data
length(gross_data1)# Missing data replaced with NA values
for (i in c(3,23,51,66,73,76,85,92,97)){
a<-gross_data1[1:(i-1)]
b<-gross_data1[i:length(gross_data1)]
gross_data1<-append(a,list("NA"))
gross_data1<-append(gross_data1,b)
}# convert the gross data to numeric
gross_data1<-as.numeric(gross_data1)
length(gross_data1)
gross_data1
Тогда результат будет выглядеть следующим образом:
Примечание: для решения проблемы с дополнительными строками в данных объекта, например gross_data, когда NA добавляется в пустые ячейки, я добавляю следующий синтаксис:
unlist(gross_data) gross_data `<- gross_data[-c(101,102)]
#если есть 102 данных
` Повторите те же действия для следующих лет до 2020 года. Убедитесь, что каждый доступный объект имеет длину 100 данных.
Затем я делаю сводку кассовых сборов с 2015 по 2020 годы.
Из результатов сводки я создаю фрейм данных, беря только среднее значение. Вот синтаксис:
# gather the data into a dataframe
average <- c(95.95, 91.77, 104.18, 103.26,
152.60, 87.42)
year <- c("2015", "2016", "2017", "2018",
"2019", "2020")
average_data = data.frame(year,average)
average_data
В первом случае я визуализирую этот фрейм данных в виде линейной диаграммы с помощью следующего синтаксиса:
plot (average_data, main = "Average Film Income",
type = "o", col = "Red", lwd = 2, xlab = "Year",
ylab = "Average Income", pch = 15)
Тогда результат будет выглядеть следующим образом:
На основе этого графика можно сделать вывод, что средний доход от фильмов каждый год имеет тенденцию к росту, с особенно значительным ростом в 2018–2019 годах. Однако в 2019–2020 годах доход снижается значительно. Это происходит из-за пандемии COVID-19, которая привела к закрытию многих кинотеатров, и, следовательно, доход от показа фильмов снизился.
Затем я создаю график, чтобы увидеть изменение тренда и дать рекомендации производителям фильмов о том, какие фильмы стоит производить. Вот синтаксис с использованием пакета gridExtra:
p1 <-qplot(data=movies2015,rating_data1,fill=genre_data1,bins=30)
p2 <-qplot(data=movies2016,rating_data2,fill=genre_data2,bins=30)
p3 <-qplot(data=movies2017,rating_data3,fill= enre_data3,bins=30)
p4 <-qplot(data=movies2018,rating_data4,fill=genre_data4,bins=30)
p5 <-qplot(data=movies2019,rating_data5,fill=genre_data5,bins=30)
p6 <-qplot(data=movies2020,rating_data6,fill=genre_data6,bins=30)
grid.arrange(p1,p2,p3,p4,p5,p6)
Тогда результат будет выглядеть следующим образом:
На основе этого графика можно сделать вывод, что люди больше всего интересуются фильмами в жанре экшн, обозначенными розовым цветом, с 2015 по 2020 годы. Розовый цвет преобладает в верхней части графика по сравнению с другими жанрами. Таким образом, нет изменений в тренде жанров среди общества.
Затем, чтобы дать рекомендации производителям фильмов, я должен также учесть кассовые сборы. Поэтому я визуализирую каждый год с помощью следующего синтаксиса:
ggplot(movies2015,aes(x=Genre2015,y=Gross_Income2015))+
geom_point(aes(size=Rating2015,col=Genre2015))
ggplot(movies2016,aes(x=Genre2016,y=Gross_Income2016))+
geom_point(aes(size=Rating2016,col=Genre2016))
ggplot(movies2017,aes(x=Genre2017,y=Gross_Income2017))+
geom_point(aes(size=Rating2017,col=Genre2017))
ggplot(movies2018,aes(x=Genre2018,y=Gross_Income2018))+
geom_point(aes(size=Rating2018,col=Genre2018))
ggplot(movies2019,aes(x=Genre2019,y=Gross_Income2019))+
geom_point(aes(size=Rating2019,col=Genre2019))
ggplot(movies2020,aes(x=Genre2020,y=Gross_Income2020))+
geom_point(aes(size=Rating2020,col=Genre2020))
Тогда результат будет выглядеть следующим образом:
На основе этого графика я могу дать следующие рекомендации производителям фильмов:
Ссылки: