CoderCastrov logo
CoderCastrov
Кинопоиск

Дух времени в кино

Дух времени в кино
просмотров
6 мин чтение
#Кинопоиск
Table Of Content

    Парсинг IMDB-Часть 2

    Гегель считал, что искусство отражает культуру времени, в котором оно было создано, «Geist Der Zeiten» или дух времени, как он называл это.

    Художественное произведение является продуктом художника, а художник является продуктом своей культуры, поэтому художественное произведение является продуктом духа этого времени.

    Гипотеза:

    Фильмы - это форма эскапизма.

    Это означает, что мы пытаемся уйти от реальности, в которой мы живем. Например, моя гипотеза состоит в том, что мы будем смотреть меньше фильмов о больных людях во время пандемии и вскоре после нее.

    Вопрос

    Может ли определенное историческое событие изменить наши предпочтения в жанре фильмов?

    • Я хотел проверить свои предположения на одном травматическом событии в нашей недавней истории и выбрал 11 сентября. Я хотел увидеть, изменяются ли наши предпочтения в жанре после насильственного события.
    • Я выбрал первые 250 самых популярных фильмов на IMDB для каждого года с 1997 по 2008 год и спарсил информацию о жанре из 2750 фильмов, сгруппированных по годам. Я посчитал, сколько раз жанр появляется в этих фильмах и составил список наиболее распространенных жанров и их соответствующее количество для каждого года. Если фильм имел более одного жанра, я добавлял каждый жанр к его количеству жанров.
    • Используя насилие как критерий, я создал систему количественной оценки жанра от 1 до 10. Например: моя система оценивает романтику на 3, а военный жанр на 10. Используя количество жанров, я умножал каждое количество жанров на их оценку и суммировал их для каждого года. Каждый год имеет оценку насилия, которая учитывает: популярность фильма, жанры и мою оценку жанра.
    • Если мое предположение о том, что мы используем фильмы для ухода от реальности, верно, то я должен увидеть уменьшение предпочтения людей к насильственным фильмам после насильственного события.

    Это больше похоже на игру, чем на науку. Я просто хотел использовать свои навыки, пытаясь найти ответы на философские вопросы, анализируя данные из IMDB.

    Если вы проверите Часть 1 моего проекта по парсингу IMDB, вы найдете функции парсинга, которые также использовались в этом проекте.

    Вы всегда должны начинать с импорта необходимых пакетов.

    import requests
    import urllib.request
    from bs4 import BeautifulSoup
    import numpy as np
    import pandas as pd
    from urllib.request import urlopen
    import matplotlib.pyplot as plt
    %matplotlib inline
    import seaborn as sns

    Создайте список жанров, которые нас интересуют.

    list_of_genres = ['фэнтези', 'экшн', 'криминал', 'драма', 'научная фантастика', 'приключения', 'комедия', 'триллер', 'мюзикл', 'вестерн', 'романтика', 'военный', 'ужасы', 'спорт', 'история', 'семейный']

    Создайте словарь с жанром в качестве ключа и оценкой «насилия» в качестве значения.

    violence_grades = {'фэнтези':3, 'экшн':7, 'криминал':9, 'драма':4, 'научная фантастика':8, 'приключения':7, 'комедия':4, 'триллер':7, 'мюзикл':4, 'вестерн':8, 'романтика':3, 'военный':10, 'ужасы':10, 'спорт':4, 'история':6, 'семейный':3}

    Я оценил «фэнтези» на 3, потому что мне кажется, что только недавно фильмы научной фантастики стали очень насильственными. Опять же, это мой личный выбор, это не предназначено для рассмотрения как научный факт.

    violence_grades_df = pd.DataFrame(violence_grades.items(), columns=['Жанры', 'Оценка_жанра'])
    violence_grades_df.set_index('Жанры')

    Наша таблица данных будет выглядеть так:

    Это функция, которая получит содержимое контейнера жанра на странице расширенного поиска IMBD.

    def get_IMDB_genres(url):
        rg = requests.get(url)
        soup = BeautifulSoup(rg.text, 'html.parser')
        movie_containers = soup.find_all('div', class_ = 'lister-item mode-advanced')
        genre_array = []
        for container in movie_containers:
            genres = container.find('span', class_ ='genre')
            if genres:
                genre_array.append(genres.text.strip())
            else:
                genre_array.append('None')
        return genre_array

    Более подробная информация о структуре веб-страницы здесь.

    Это функция, которая получит список фильмов для каждого года и оценку насилия для года.

    def get_IMDB_genre_popularity(year):
        url = 'https://www.imdb.com/search/title/?title_type=feature&release_date='+str(year)+'-01-01,'+str(year)+'-12-31&user_rating=5.0,10.0&countries=us&sort=moviemeter,desc&count=250'
        f = get_IMDB_genres(url)
        action_count = 0
        for item in f:
            if 'Action' in item:
                action_count += 1
        comedy_count = 0
        for item in f:
            if 'Comedy' in item:
                comedy_count += 1 
        adventure_count = 0
        for item in f:
            if 'Adventure' in item:
                adventure_count += 1
        drama_count = 0
        for item in f:
            if 'Drama' in item:
                drama_count += 1
        romance_count = 0
        for item in f:
            if 'Romance' in item:
                romance_count += 1  
        western_count = 0
        for item in f:
            if 'Western' in item:
                western_count += 1
        thriller_count = 0
        for item in f:
            if 'Thriller' in item:
                thriller_count += 1
        horror_count = 0
        for item in f:
            if 'Horror' in item:
                horror_count += 1
        crime_count = 0
        for item in f:
            if 'Crime' in item:
                crime_count += 1
        scifi_count = 0
        for item in f:
            if 'Sci' in item:
                scifi_count += 1
        family_count = 0
        for item in f:
            if 'Family' in item:
                family_count += 1
        history_count = 0
        for item in f:
            if 'History' in item:
                history_count += 1
        war_count = 0
        for item in f:
            if 'War' in item:
                war_count += 1
        fantasy_count = 0
        for item in f:
            if 'Fantasy' in item:
                fantasy_count += 1
        sport_count = 0
        for item in f:
            if 'Sport' in item:
                sport_count += 1
        musical_count = 0
        for item in f:
            if 'Musical' in item:
                musical_count += 1
        genre_counts = {'фэнтези':fantasy_count,
                        'экшн':action_count,
                        'криминал':crime_count,
                        'драма':drama_count,
                        'научная фантастика':scifi_count,
                        'приключения':adventure_count,
                        'комедия':comedy_count,
                        'триллер':thriller_count,
                        'мюзикл':musical_count,
                        'вестерн':western_count,
                        'романтика':romance_count,
                        'военный':war_count,
                        'ужасы':horror_count,
                        'спорт':sport_count,
                        'история':history_count,
                        'семейный':family_count }
        df_to_plot = pd.DataFrame(genre_counts.items(), columns=['Жанры', 'Количество_жанров'])
        years = [year]*len(df_to_plot)
        df_to_plot['year'] = years
        Zeitgeist_df = violence_grades_df.join(df_to_plot.set_index('Жанры'), on='Жанры')
        Zeitgeist_df['Оценка_насилия_года'] = Zeitgeist_df['Оценка_жанра']*Zeitgeist_df['Количество_жанров']
        del Zeitgeist_df['Оценка_жанра']
        del Zeitgeist_df['Количество_жанров']
        return Zeitgeist_df

    Это итоговый DataFrame для года 1950.

    В 1950 году был выпущен один фэнтезийный фильм. Если мы умножим 1 на оценку, которую у нас есть для фэнтези (3), то получим результат 3.

    Мы создаем DataFrame со всеми годами и соответствующей оценкой, используя функцию pandas concat.

    pieces = []
    for year in [*range(1997,2009,1)]:
        df= get_IMDB_genre_popularity(year)
        pieces.append(df)
    df_all = pd.concat(pieces)
    df_all.set_index('Жанры')
    df_all

    Это объединенный DataFrame.

    Если сложить все оценки для года, вы получите одну оценку для года. Мы также можем получить среднее значение вместо суммы.

    grouped = df_all.groupby(['year'])['Оценка_насилия_года'].sum()

    Вот как выглядит наш итоговый DataFrame.

    Мы добавили событие 11 сентября и «Великую рецессию 2008 года» в наш DataFrame.

    events_dict = {1950: 'Корейская война', 1955:'Вьетнамская война', 1989:'Падение Берлинской стены', 1992:'Падение СССР', 2001:'11 сентября и война в Афганистане', 2007:'Великая рецессия'}
    events_df = pd.DataFrame(events_dict.items(), columns=['year', 'events'])
    events_df.set_index('year')
    df_Zeitgeist_final = df_Zeitgeist_grouped.join(events_df.set_index('year'), on='year')
    df_Zeitgeist_final

    Это итоговый DataFrame, который мы собираемся использовать для построения графика.

    Давайте построим наши данные.

    fig = plt.figure(figsize=(70,40))
    ax = plt.subplot(1,1,1)
    plt.style.use('seaborn-darkgrid')
    ax1= plt.subplot(4,4,1)
    ax1.plot(df_Zeitgeist_grouped['year'], df_Zeitgeist_grouped['Оценка_насилия_года'], color = 'orange', linestyle = '-', linewidth=5)
    symbol4= '9/11'
    ax1.plot(2002, 1329,'ro', markersize = 35, marker = r"$ {} $".format(symbol4))
    ax1.plot(2001, 1329,'ro', markersize = 10, marker = 'o')
    symbol5='Великая рецессия'
    ax1.plot(2010, 1875,'ro', markersize = 140, marker = r"$ {} $".format(symbol5))
    ax1.plot(2008, 1875,'ro', markersize = 10, marker = 'o')
    plt.xlabel("", fontsize=30)
    plt.ylabel("", fontsize=30)
    ax1.set_xlabel('Год')
    ax1.set_ylabel('Оценка насилия')
    xticks = [*range(1997,2015,1)]
    plt.xticks(xticks);

    Вот траектория насилия в фильмах с 1997 по 2008 год.


    ВЫВОДЫ

    После 11 сентября произошло резкое снижение насилия в фильмах.

    Почему?

    Если моя игра имеет что-то общее с реальностью, то мы можем объяснить снижение временем, необходимым для завершения проекта фильма. Только фильмы, начатые после 11 сентября, окажут влияние на оценку «насилия», и иногда требуется более года или даже двух, чтобы завершить проект.

    Сохраняется ли моя теория на более длительный период времени?

    Давайте посмотрим с 1950 по 2019 год.

    Ответ - нет.

    Причина неудачи моей модели на более длительный период времени заключается в том, что мы выражаем свои предпочтения на веб-сайте IMDB, а интернет был изобретен в 1990 году и стал широко доступен только после 2000 года.

    Я оцениваю фильм, например, «Colt 45», выпущенный в 1950 году, одним способом, но человек из 1950-х годов смотрел бы совершенно другой фильм.

    На графике отражается не дух 1950-х годов, а то, как мы видим фильм 1950 года.