Як витягти дані з 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 Коментаріїв