CoderCastrov logo
CoderCastrov
Парсер

Парсинг Топ-100 фильмов IMDb 2015–2020 (R)

Парсинг Топ-100 фильмов IMDb 2015–2020 (R)
просмотров
5 мин чтение
#Парсер

Привет, друзья! В этом руководстве я попробую получить данные о 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

Тогда результат будет выглядеть следующим образом:

Genre Top 100 Movies (2015)

Затем я делаю то же самое, чтобы увидеть позицию рейтинга, используя расширение 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

Тогда результат будет выглядеть следующим образом:

Rating Top 100 Movies (2015)

Затем я парсю данные о кассовых сборах. Когда я проверил длину данных, оказалось, что нет 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 IncomeTop 100 Movies (2015)

Примечание: для решения проблемы с дополнительными строками в данных объекта, например gross_data, когда NA добавляется в пустые ячейки, я добавляю следующий синтаксис:

unlist(gross_data) gross_data `<- gross_data[-c(101,102)] 
#если есть 102 данных

` Повторите те же действия для следующих лет до 2020 года. Убедитесь, что каждый доступный объект имеет длину 100 данных.

Затем я делаю сводку кассовых сборов с 2015 по 2020 годы.

Summary Gross Income (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)

Тогда результат будет выглядеть следующим образом:

Line Chart Gross Income Movies

На основе этого графика можно сделать вывод, что средний доход от фильмов каждый год имеет тенденцию к росту, с особенно значительным ростом в 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)

Тогда результат будет выглядеть следующим образом:

Plot Based on Rating and Genre

На основе этого графика можно сделать вывод, что люди больше всего интересуются фильмами в жанре экшн, обозначенными розовым цветом, с 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))

Тогда результат будет выглядеть следующим образом:

ggplot Movies (2015) ggplot Movies (2016) ggplot Movies (2017) ggplot Movies (2018) ggplot Movies (2019) ggplot Movies (2020)

На основе этого графика я могу дать следующие рекомендации производителям фильмов:


Ссылки:


Парсинг веб-страниц с использованием R

medium.com

RPubs

Описание

www.rpubs.com