Как извлечь данные с IMDB с использованием Python

Комментарии: 0

Извлечение данных из онлайн-платформ, таких как IMDB, является эффективным методом сбора необходимой информации о фильмах для исследовательских целей. В данном руководстве рассмотрен процесс скрапинга топ-250 фильмов на IMDB с использованием Python, а также извлечение таких деталей, как названия фильмов, аннотации, рейтинги, жанры и другое.

При скрапинге сайтов, подобных IMDB, важно имитировать поведение реального пользователя, используя соответствующие заголовки и иногда прокси. Это способствует:

  1. Избежанию блокировки по IP: многие сайты ограничивают количество запросов с одного IP. Использование прокси позволяет распределить запросы по разным IP-адресам.
  2. Обеспечению анонимности: прокси-серверы скрывают реальный IP-адрес пользователя, создавая достоверные запросы из разных локаций, и обеспечивая приватность в интернете.
  3. Соблюдению лимитов скорости: прокси-серверы позволяют распределять запросы по разным IP-адресам, что помогает избежать превышения лимитов скорости, установленных сервером.
  4. Обход подозрений серверов: Использование заголовков, таких как User-Agent, делает запросы менее подозрительными, создавая впечатление, что они поступают от реальных пользователей и настоящих браузеров.

Шаг 1: Подготовка скрапера

В рамках данного руководства используются библиотека requests для загрузки контента, библиотека lxml для парсинга HTML-контента и библиотека JSON для обработки форматированных данных.

Установка библиотек

Сначала установите необходимые библиотеки:


pip install requests lxml

Эти библиотеки будут использоваться для отправки HTTP-запросов, парсинга HTML-контента и обработки извлеченных данных.

Конфигурация заголовков HTTP-запроса

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


import requests

headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-IN,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',  # Заголовок Do Not Track
    'pragma': 'no-cache',
    'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Linux"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
}

response = requests.get('https://www.imdb.com/chart/top/', headers=headers)

Настройка прокси

Прокси оказываются крайне полезными при масштабном скрапинге данных. Они позволяют избежать блокировок за счет распределения запросов через несколько IP-адресов. Вот как можно настроить использование прокси:


proxies = {
    "http": "http://your_proxy_server",
    "https": "https://your_proxy_server"
}

response = requests.get('https://www.imdb.com/chart/top/', headers=headers, proxies=proxies)

Замените “your_proxy_server” на актуальные данные от прокси, к которым у вас есть доступ. Это обеспечивает сохранение конфиденциальности IP-адреса и помогает избежать блокировок при активном скрапинге.

Шаг 2: Парсинг HTML-контента

После получения содержимого веб-страницы необходимо проанализировать его для извлечения данных о фильмах. Для парсинга HTML будет использоваться библиотека lxml, а для работы со структурированными данными — json:


from lxml.html import fromstring
import json

# Парсинг HTML-ответа
parser = fromstring(response.text)

# Извлечение данных JSON-LD (структурированные данные) из тега script
raw_data = parser.xpath('//script[@type="application/ld+json"]/text()')[0]
json_data = json.loads(raw_data)

# Теперь у нас есть структурированные данные о фильмах в формате JSON

Шаг 3: Извлечение данных о фильмах

Страница «Топ 250 фильмов» на IMDB содержит структурированные данные, внедренные в HTML, к которым можно легко получить доступ с помощью XPath и которые можно анализировать как JSON. Будут извлечены такие данные фильмов, как название, описание, рейтинги, жанры и другое:


movies_details = json_data.get('itemListElement')

# Цикл по данным о фильмах
movies_data = []
for movie in movies_details:
    movie_type = movie['item']['@type']
    url = movie['item']['url']
    name = movie['item']['name']
    description = movie['item']['description']
    image = movie['item']['image']
    bestRating = movie['item']['aggregateRating']['bestRating']
    worstRating = movie['item']['aggregateRating']['worstRating']
    ratingValue = movie['item']['aggregateRating']['ratingValue']
    ratingCount = movie['item']['aggregateRating']['ratingCount']
    contentRating = movie['item'].get('contentRating')
    genre = movie['item']['genre']
    duration = movie['item']['duration']
    
    # Добавление данных каждого фильма в список
    movies_data.append({
        'movie_type': movie_type,
        'url': url,
        'name': name,
        'description': description,
        'image': image,
        'bestRating': bestRating,
        'worstRating': worstRating,
        'ratingValue': ratingValue,
        'ratingCount': ratingCount,
        'contentRating': contentRating,
        'genre': genre,
        'duration': duration
    })

Шаг 4: Сохранение данных

После извлечения данных важно сохранить их в формате, который удобно анализировать. В данном случае данные будут сохранены в файл CSV с использованием библиотеки pandas:


import pandas as pd

# Преобразование списка фильмов в DataFrame pandas
df = pd.DataFrame(movies_data)

# Сохранение данных в файл CSV
df.to_csv('imdb_top_250_movies.csv', index=False)

print("IMDB Top 250 movies data saved to imdb_top_250_movies.csv")

Финальная версия кода

Ниже представлен полный код для скрапинга топ-250 фильмов IMDB:


import requests
from lxml.html import fromstring
import json
import pandas as pd

# Определение заголовков для запроса
headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-IN,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',
    'pragma': 'no-cache',
    'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Linux"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
}

# Настройка прокси (опционально)
proxies = {
    "http": "http://your_proxy_server",
    "https": "https://your_proxy_server"
}

# Отправка запроса на страницу топ-250 фильмов IMDB
response = requests.get('https://www.imdb.com/chart/top/', headers=headers, proxies=proxies)

# Парсинг HTML-ответа
parser = fromstring(response.text)

# Извлечение данных JSON-LD
raw_data = parser.xpath('//script[@type="application/ld+json"]/text()')[0]
json_data = json.loads(raw_data)

# Извлечение данных о фильмах
movies_details = json_data.get('itemListElement')

movies_data = []
for movie in movies_details:
    movie_type = movie['item']['@type']
    url = movie['item']['url']
    name = movie['item']['name']
    description = movie['item']['description']
    image = movie['item']['image']
    bestRating = movie['item']['aggregateRating']['bestRating']
    worstRating = movie['item']['aggregateRating']['worstRating']
    ratingValue = movie['item']['aggregateRating']['ratingValue']
    ratingCount = movie['item']['aggregateRating']['ratingCount']
    contentRating = movie['item'].get('contentRating')
    genre = movie['item']['genre']
    duration = movie['item']['duration']
    
    movies_data.append({
        'movie_type': movie_type,
        'url': url,
        'name': name,
        'description': description,
        'image': image,
        'bestRating': bestRating,
        'worstRating': worstRating,
        'ratingValue': ratingValue,
        'ratingCount': ratingCount,
        'contentRating': contentRating,
        'genre': genre,
        'duration': duration
    })

# Сохранение данных в файл CSV
df = pd.DataFrame(movies_data)
df.to_csv('imdb_top_250_movies.csv', index=False)
print("IMDB Top 250 movies data saved to imdb_top_250_movies.csv")

Этические аспекты скрапинга

Перед началом скрапинга любого веб-сайта важно учитывать этические и юридические аспекты:

  • Robots.txt. Проверьте файл robots.txt на IMDB, чтобы узнать, какие части сайта разрешены для скрапинга. Всегда следуйте политике веб-сайта.
  • Избегание перегрузки сервера. Ответственно подходите к скрапингу, ограничивая частоту своих запросов, чтобы не создавать избыточную нагрузку на сервер.
  • Соблюдение условий использования. Убедитесь, что скрапинг не нарушает условия использования IMDB.

Всегда помните о правилах и используйте веб-скрапинг для законных целей.

Комментарии:

0 комментариев