В этом сообщении показано, как создать набор данных о фильмах с помощью Python и API OMDb. Это будет сделано с использованием списка извлеченных названий фильмов, показанных в предыдущем посте «movie-data-collection-part-1-web-scraping-using-python».
Во-первых, в нем представлены различные методы сбора или парсинга данных. Во-вторых, будет кратко рассмотрен API OMDb. Наконец, показано, как создается набор данных с помощью Python.
Сбор онлайн-данных
Сбор онлайн-данных, также называемый парсингом, часто включает в себя извлечение неорганизованных данных и организацию их в виде электронной таблицы. Существует несколько способов сбора данных из онлайн-источников. Среди них ручное копирование и вставка, синтаксический анализ HTML, синтаксический анализ DOM и использование существующего веб-API¹.
Копирование и вставка вручную просто включает копирование значения из источника в Интернете и вставку его в электронную таблицу, например. превосходить
Синтаксический анализ HTML включает в себя использование базовой структуры, из которой состоит веб-страница, и преобразование ее во что-то, с чем может работать программа. Веб-страница состоит из тегов, атрибутов и элементов. Разбор HTML-документа с помощью языка программирования позволяет распознавать составляющие страницы и извлекать из нее данные. Распространенным способом в Python является использование библиотеки BeatuifulSoup.
Синтаксический анализ DOM включает преобразование веб-страницы в логическую структуру, обеспечивающую доступность и манипулирование². Используя дополнительные инструменты, такие как Xpath, вы можете извлечь из него данные. Это отличный метод для парсинга динамических веб-страниц. В Python для этого можно использовать библиотеку Selenium.
Иногда разработчики могут использовать существующие веб-API. Затем разработчики могут напрямую взаимодействовать с базой данных и извлекать данные, которые существуют среди многих других для Twitter и Google Maps. Эти API используют стандартные методы и документацию о том, как извлекать, публиковать или удалять информацию.
Основное преимущество использования существующих веб-API заключается в том, что данные часто уже структурированы (помечены). Хотя другие инструменты парсинга полезны, разметка веб-страницы часто неструктурирована. Поэтому маркировка данных может занять много времени. Кроме того, есть недостаток, когда дело доходит до обслуживания. Небольшие изменения на веб-сайте могут со временем сделать ваш скрипт бесполезным.
API OMDb
OMDb (открытая база данных фильмов) RESTful API. Это веб-сервис, который позволяет вам получить доступ к информации о фильме, указав название фильма или идентификатор imdb. На веб-сайте вы можете запросить бесплатный ключ API, который позволит вам получить доступ
API, сокращенно от интерфейса прикладного программирования, — это программное обеспечение, которое обеспечивает общность между различными программными системами, позволяя им обмениваться информацией друг с другом³.
REST или Передача репрезентативного состояния просто относится к архитектурному дизайну API. Как правило, эти APIS используют HTTP (протокол передачи гипертекста) и используют стандартные методы, такие как GET, POST, PUT и DELETE⁴.
Всякий раз, когда предоставляется название фильма или идентификатор imdb, OMDdb возвращает изображение объекта JSON ниже⁵. Для получения дополнительной информации https://www.omdbapi.com/.
{"Title":"The Avengers", "Year":"2012", "Rated":"PG-13", "Released":"04 May 2012", "Runtime":"143 min", "Genre":"Action, Sci-Fi", "Director":"Joss Whedon", "Writer":"Joss Whedon, Zak Penn", "Actors":"Robert Downey Jr., Chris Evans, Scarlett Johansson", "Plot":"Earth's mightiest heroes must come together and learn to fight as a team if they are going to stop the mischievous Loki and his alien army from enslaving humanity.","Language":"English, Russian, Hindi","Country":"United States","Awards":"Nominated for 1 Oscar. 38 wins & 80 nominations total","Poster":"https://m.media-amazon.com/images/M/MV5BNDYxNjQyMjAtNTdiOS00NGYwLWFmNTAtNThmYjU5ZGI2YTI1XkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_SX300.jpg", "Ratings":[{"Source":"Internet Movie Database","Value":"8.0/10"}, {"Source":"Rotten Tomatoes","Value":"91%"}, {"Source":"Metacritic","Value":"69/100"}], "Metascore":"69", "imdbRating":"8.0", "imdbVotes":"1,397,515", "imdbID":"tt0848228", "Type":"movie", "DVD":"25 Sep 2012", "BoxOffice":"$623,357,910", "Production":"N/A", "Website":"N/A", "Response":"True"}
Как видно из выходных данных выше, каждое значение помечено. На момент написания OMDb API предлагает 1000 запросов в день бесплатно. Это можно увеличить, имея учетную запись Patreon.
Сбор данных с помощью Python
Для извлечения и организации данных соответственно используются две библиотеки Requests и Pandas.
Запросы позволяют выполнять HTTP-запросы, предоставляя URL-адрес. HTTP-запросы выполняются клиентом к хосту, расположенному на сервере, для доступа к информации.
Pandasиспользуется для сохранения данных во фрейме данных (или в структуре, подобной электронной таблице).
В приведенном ниже блоке кода показано, как извлечь данные с помощью API для одного фильма.
Сбор данных для одного фильма
Сначала создается URL-адрес с использованием ключа API и названия фильма. Обратите внимание, что ключ API хранится в переменной с именем api_key. Как упоминалось ранее, персональный ключ можно запросить на веб-сайте.
Используя функцию get(), данные можно получить, используя URL-адрес в качестве входных данных. объект ответа хранится в переменной ответа. Метод status_code можно использовать для определения того, был ли запрос успешным, это тот случай, когда он возвращает значение 200. С помощью метода json() можно просмотреть содержимое запроса. (Вы могли заметить, что объекты JSON напоминают словарь Python, состоящий из ключей и значений.)
#importing libraries import pandas as pd import requests # Movie name movie_name = 'the Avengers' #url url = 'https://www.omdbapi.com/?apikey='+ api_key + '={}'.format(movie_name) response = requests.get(url) print(response.status_code) print(response.json()) >>> print(response.status_code) 200 >>> print(response.json()) {'Title': 'The Avengers', 'Year': '2012', 'Rated': 'PG-13', 'Released': '04 May 2012', 'Runtime': '143 min', 'Genre': 'Action, Sci-Fi', 'Director': 'Joss Whedon', 'Writer': 'Joss Whedon, Zak Penn', 'Actors': 'Robert Downey Jr., Chris Evans, Scarlett Johansson', 'Plot': "Earth's mightiest heroes must come together and learn to fight as a team if they are going to stop the mischievous Loki and his alien army from enslaving humanity.", 'Language': 'English, Russian, Hindi', 'Country': 'United States', 'Awards': 'Nominated for 1 Oscar. 38 wins & 80 nominations total', 'Poster': 'https://m.media-amazon.com/images/M/MV5BNDYxNjQyMjAtNTdiOS00NGYwLWFmNTAtNThmYjU5ZGI2YTI1XkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_SX300.jpg', 'Ratings': [{'Source': 'Internet Movie Database', 'Value': '8.0/10'}, {'Source': 'Rotten Tomatoes', 'Value': '91%'}, {'Source': 'Metacritic', 'Value': '69/100'}], 'Metascore': '69', 'imdbRating': '8.0', 'imdbVotes': '1,402,797', 'imdbID': 'tt0848228', 'Type': 'movie', 'DVD': '25 Sep 2012', 'BoxOffice': '$623,357,910', 'Production': 'N/A', 'Website': 'N/A', 'Response': 'True'}
Сбор данных для нескольких фильмов
Как показано, API Omdb отвечает на входные данные для возврата данных характеристик фильма. Поэтому для создания набора данных требуется коллекция названий фильмов. Есть несколько способов получить названия фильмов (например, просто спросите в chatGPT3). В предыдущем посте «кино-данные-сбор-часть-1-веб-скрейпинг-использование-питона». Там Википедия была очищена от названий фильмов с помощью BeautifulSoup. вывод сохраняется в переменной movie_names как объект pd.Series.
#Series containing movie names movie_names >>> movie_names 2 Digger 3 Detention 4 Deathstalker ... 57399 The Cleaner 57400 Crashout 57401 Cheetah 57402 The Contact 57403 The Champion Length: 57404, dtype: object
Создание набора данных
Переменная имен фильмов позволяет выполнять итерацию по имени каждого фильма, запрашивать данные функций и сохранять их во фрейме данных. Это выполняется с помощью двух функций.
Первая функция принимает серию названий фильмов в качестве входных данных, перебирает каждое название фильма, выполняет запрос get(), добавляет два списка и возвращает следующие выходные данные.
- Список unique_keys, в котором хранятся все уникальные ключи данных, возвращенные ответами JSON. Они будут служить именами столбцов фрейма данных (или метками). Это необходимо, потому что не каждый запрос возвращает точные ключи.
- json_responses — это список, содержащий объекты JSON, где каждый объект — это данные фильма, возвращаемые запросом get().
#Takes a list of movie names and returns features using the API def get_movie_data(movie_names): #initiate empty list to capture all json json_responses = [] #initiate empty list that stores a possible feature possible_keys = [] #iterate through movie list for name in movie_names: #Request movie title using omdbAPI response = requests.get( 'https://www.omdbapi.com/?apikey='+ api_key + '={}'.format(name)) #Find all keys associated with the request extent the key list possible_keys.extend( list(response.json().keys())) #append moviename nested_list_movies.append(response.json()) #Remove all duplicated keys/features unique_keys = set(possible_keys) return unique_keys, json_responses unique_keys, json_responses = get_movie_data(subset_movie_names) >>> unique_keys {'Awards', 'Year', 'Genre', 'Metascore', 'imdbID', 'Title', 'Language', 'Production', 'Runtime', 'Actors', 'Country', 'Released', 'Plot', 'Website', 'BoxOffice', 'Error', 'Poster', 'Ratings', 'DVD', 'Writer', 'Response', 'totalSeasons', 'Rated', 'imdbRating', 'imdbVotes', 'Type', 'Director'} >>> json_responses[4:6] [{'Title': 'Deathstalker', 'Year': '1983', 'Rated': 'R', 'Released': '16 Sep 1983', 'Runtime': '80 min', 'Genre': 'Action, Adventure, Fantasy', 'Director': 'James Sbardellati', 'Writer': 'Howard R. Cohen', 'Actors': 'Rick Hill, Barbi Benton, Richard Brooker', 'Plot': 'A lone warrior nicknamed Deathstalker is sent by a witch on a quest to find a sword, a chalice, and an amulet, two of which are held by the wicked king and sorcerer, Munkar.', 'Language': 'English', 'Country': 'United States, Argentina', 'Awards': 'N/A', 'Poster': 'https://m.media-amazon.com/images/M/MV5BNzJlMDEwMTgtMGI5Ny00ODAzLThhM2UtYmRkYjc3OTRiZDQ0XkEyXkFqcGdeQXVyMTQ2MjQyNDc@._V1_SX300.jpg', 'Ratings': [{'Source': 'Internet Movie Database', 'Value': '4.6/10'}], 'Metascore': 'N/A', 'imdbRating': '4.6', 'imdbVotes': '5,524', 'imdbID': 'tt0087127', 'Type': 'movie', 'DVD': '18 Jun 2018', 'BoxOffice': '$11,919,250', 'Production': 'N/A', 'Website': 'N/A', 'Response': 'True'} ,{'Title': 'Daadi Maa', 'Year': '1966', 'Rated': 'Not Rated', 'Released': 'N/A', 'Runtime': '171 min', 'Genre': 'Action, Comedy, Drama', 'Director': 'L.V. Prasad', 'Writer': 'Mukhram Sharma', 'Actors': 'Ashok Kumar, Bina Rai, Dilip Raj', 'Plot': 'Pratap lives a wealthy lifestyle in a mansion along with his mother, Maharani. He is married to Parvati but the couple are childless. Then differences arise between the two on one hand, and Maharani and Pratap on the other. Parvat...', 'Language': 'Hindi', 'Country': 'India', 'Awards': 'N/A', 'Poster': 'https://m.media-amazon.com/images/M/MV5BZDI3MDIyODYtOTdlYi00MjcwLWE1MWMtMDk1Yjg1MzhjOTlhXkEyXkFqcGdeQXVyNjY1MTg4Mzc@._V1_SX300.jpg', 'Ratings': [{'Source': 'Internet Movie Database', 'Value': '5.9/10'}], 'Metascore': 'N/A', 'imdbRating': '5.9', 'imdbVotes': '29', 'imdbID': 'tt0175546', 'Type': 'movie', 'DVD': '28 Sep 2017', 'BoxOffice': 'N/A', 'Production': 'N/A', 'Website': 'N/A', 'Response': 'True'}]
Вторая функция принимает в качестве входных данных список unique_keys и список json_responses. Создает словарь с именем movie_dict, где уникальные ключи — это ключи словаря, а значение — пустой список.
Использование вложенного цикла for для каждого объекта JSON и ключа movie_dictionary. Он извлекает значения из объекта JSON, где ключ объекта JSON соответствует ключу в movie_dict. Затем он добавляет значение объекта JSON в пустой список соответствующего ключа (метки) в movie_dict.
Всякий раз, когда movie_dict содержит ключ, которого нет в объекте JSON, для этого наблюдения возвращается значение None.
Наконец, после извлечения всех значений из каждого объекта JSON. Movie_dict преобразуется в DataFrame pandas.
def create_movie_df( keys, list_jsons): #initiate empty dictionary that stores all unique keys movie_dict = {key:[] for key in keys} #Iterate through saved movie data and append data to corresponding key for json in list_jsons: #capture value if error return value = none for key in movie_dict: try: value = json[key] except KeyError: value = None #Append value to corresponding key in movie dict movie_dict[key].append(value) #Transform dictionary to dataframe movie_df = pd.DataFrame.from_dict( movie_dict, orient='columns') return movie_df #Create movie df movie_df = create_movie_df( keys = unique_keys, list_jsons=json_responses ) # return dimension of DataFrame movie_df.shape #Return first 100 rows movie_df[0:100] >>> movie_df = create_movie_df( ... keys = unique_keys, ... list_jsons=json_responses ... ) >>> movie_df.shape (57377, 27) >>> movie_df[0:100] Awards Year ... Type Director 0 N/A 1995 ... movie S.A. Chandrashekhar 1 None None ... None None 2 21 wins & 24 nominations 2020 ... movie Georgis Grigorakis 3 4 nominations 2011 ... movie Joseph Kahn 4 N/A 1983 ... movie James Sbardellati .. ... ... ... ... ... 95 N/A 1978 ... movie Walter Hill 96 None None ... None None 97 N/A 1958 ... movie Tara Harish 98 6 wins & 10 nominations 2021 ... movie Ana Katz 99 2 wins 2022 ... movie Reid Carolin, Channing Tatum [100 rows x 27 columns] >>>
Результатом является DataFrame, состоящий из 57377 строк данных фильма. В реальности это меньше, потому что на данном этапе данные еще не были очищены.
Источники:
- Авторы Википедии. (2023, 3 февраля). Скрапинг веб-страниц. Википедия. https://en.wikipedia.org/wiki/Web_scraping
- Что такое объектная модель документа? (без даты). https://www.w3.org/TR/WD-DOM/introduction.html#:~:text=The%20Document%20Object%20Model%20(DOM,document%20is%20доступен%20и%20манипулируется.)
- Офеда Дж., Боатенг Р. и Эффа Дж. (2019) Исследование интерфейса прикладного программирования (API), International Journal of Enterprise Information Systems, 15(3), стр. 76– 95. Доступно по адресу: https://doi.org/10.4018/ijeis.2019070105.
- Эхсан А., Абухалика М. а. ME, Родригес, Д., и Мишра, Д. (2022). Методологии тестирования RESTful API: обоснование, проблемы и направления решения. Applied Sciences, 12(9), 4369. https://doi.org/10.3390/app12094369
- OMDb API — открытая база данных фильмов. (н.д.). https://www.omdbapi.com/