Скрапинг IMDb с помощью Python: код, который действительно работает

Последнее обновление: April 28, 2026

Если вы недавно искали «scrape IMDb with Python», вы наверняка заметили одну вещь: большинство найденных туториалов уже сломаны. Не «чуть устарели», а именно «возвращают ноль результатов и кучу ошибок NoneType».

Последние несколько недель я тестировал каждый крупный туториал по парсингу IMDb, который смог найти: GeeksforGeeks, Medium, freeCodeCamp, ноутбуки Kaggle — всё подряд. Из с тегом IMDb scraping подавляющее большинство ссылается на CSS-селекторы (td.titleColumn, td.ratingColumn), которых не существует с июня 2023 года, когда IMDb обновил страницу Top 250. Итог? Форумы завалены разработчиками, которые спрашивают: «почему мой код возвращает пусто?», а мейнтейнеры популярных библиотек вроде : «Мы мало что можем сделать, кроме как чинить каждый парсер». Это руководство охватывает два метода на Python, которые действительно работают прямо сейчас, как обрабатывать пагинацию и типичные ошибки, когда Python вообще не лучший инструмент, и как сделать ваш скрейпер более устойчивым к будущим изменениям, чтобы он не отправился на кладбище вместе с остальными.

Что значит парсить IMDb с помощью Python?

Веб-скрапинг — это программное извлечение данных с веб-страниц: вместо ручного копирования и вставки вы пишете скрипт, который делает это за вас. Когда мы говорим о «скрапинге IMDb», мы имеем в виду извлечение структурированных данных о фильмах — названий, рейтингов, жанров, актёрского состава, хронометража, количества голосов — со страниц IMDb с помощью Python.

Типичный Python-стек для этого включает три библиотеки: requests (чтобы получить веб-страницу), BeautifulSoup (чтобы разобрать HTML и найти данные) и pandas (чтобы упорядочить и экспортировать результаты). В некоторых туториалах также используют Selenium или Playwright для страниц, которым нужен JavaScript-рендеринг, но, как вы увидите, есть и более быстрые подходы.

Важная оговорка: всё в этом руководстве проверено на актуальной структуре страниц IMDb на середину 2025 года. IMDb меняет что-то примерно каждые 6–12 месяцев, так что если вы читаете это в 2027 году, некоторые селекторы могли измениться. (Я тоже объясню, как с этим работать.)

Зачем парсить IMDb с помощью Python? Реальные сценарии

Прежде чем написать хотя бы одну строку кода, стоит понять: что вы вообще будете делать с данными IMDb? Ответ зависит от того, кто вы.

Датасет с отзывами IMDb — один из самых широко используемых бенчмарков NLP в мире: базовая статья Maas et al. (2011) собрала , а сам датасет встроен в TensorFlow, Keras и PyTorch. На Hugging Face датасет stanfordnlp/imdb скачивают 213 321 раз в месяц, и на нём обучили более 1500 моделей. Так что, если вы работаете с машинным обучением, вы, скорее всего, уже знакомы с данными IMDb.

Но сценарии использования выходят далеко за рамки академии:

СценарийДля когоКакие поля нужны
Система рекомендаций фильмовData scientists, энтузиастыНазвания, жанры, рейтинги, актёры
Контент-стратегия стриминговой платформыКоманды продукта и контентаРейтинги, голоса, год выпуска, жанры
Анализ тональности / обучение NLPИсследователи ML, студентыОтзывы, рейтинги
Анализ конкурентного контентаАналитики индустрии развлеченийКассовые сборы, даты релиза, динамика рейтингов
Исследования кинокомиссий и туризмаТуристические ведомства, travel-компанииМеста съёмок, метрики популярности
Академические исследованияУниверситетские исследователиЛюбые структурированные метаданные о фильмах

Только рынок кинотуризма, по оценкам, стоит . Netflix в 2024 году потратил на контент более $17 млрд, а формируется за счёт персонализированных рекомендаций. Суть в том, что данные IMDb лежат в основе реальных решений в разных отраслях.

Какие есть способы получить данные IMDb, прежде чем писать код

Это раздел, который большинство туториалов полностью пропускает. Они сразу переходят к pip install beautifulsoup4, не задавшись вопросом, действительно ли скрапинг на Python — правильный путь именно для вашей задачи.

Полная картина выглядит так:

ПутьЛучше всего подходит дляПлюсыМинусы
Python + BeautifulSoupОбучения, кастомного извлеченияПолный контроль, гибкостьХрупкие селекторы, часто ломается
Извлечение JSON-LD / __NEXT_DATA__Разработчиков, которым нужна стабильностьРаботает с JS-контентом, устойчивееНужно понимать структуру JSON
Официальные датасеты IMDbКрупномасштабного анализа, академического использованияЛегально, полно, 26M+ тайтлов, ежедневные обновленияTSV-формат, нет отзывов/изображений
Библиотека Cinemagoer (IMDbPY)Программных запросов по тайтламPython API, богатые поля88 открытых issues, последний релиз — май 2023
TMDb APIМетаданные фильмов + изображенияБесплатный API-ключ, JSON, хорошая документацияДругой источник (не рейтинги IMDb)
Thunderbit (no-code)Тем, кто не пишет код, быстрым экспортамСкрапинг в 2 клика, AI предлагает поля, экспорт в Excel/SheetsДля больших объёмов — модель на кредитах

Пара замечаний по этим вариантам. У Cinemagoer не было релиза в PyPI с мая 2023 года, и большинство его парсеров сломалось после редизайна IMDb в июне 2025-го — для продакшена я бы сейчас его не рекомендовал. TMDb хорош, но использует собственную систему рейтингов, а не IMDb. И официальный enterprise API IMDb через AWS Data Exchange стоит , так что для большинства из нас это не вариант.

Для тех, кто вообще не хочет писать код, читает страницу IMDb, автоматически предлагает поля извлечения (название, рейтинг, год, жанр) и экспортирует в Excel, Google Sheets, Airtable или Notion в два клика. AI подстраивается, когда IMDb меняет разметку, так что не нужно поддерживать селекторы. Об этом — чуть позже.

А теперь для тех, кто всё же хочет писать на Python — вот два рабочих метода.

Метод 1: парсинг IMDb на Python с BeautifulSoup (классический подход)

Это классический способ, который вы найдёте в большинстве туториалов. Он работает, но скажу прямо: это самый хрупкий из методов, которые я здесь разбираю. CSS-классы IMDb генерируются автоматически и меняются при редизайне. При этом это лучший способ изучить основы веб-скрапинга.

Шаг 1: установите и импортируйте библиотеки Python

Вам нужны четыре пакета:

1pip install requests beautifulsoup4 pandas lxml

Что делает каждый из них:

  • requests — отправляет HTTP-запросы, чтобы получить веб-страницу
  • beautifulsoup4 — разбирает HTML, чтобы можно было искать конкретные элементы
  • pandas — упорядочивает извлечённые данные в таблицы и экспортирует в CSV/Excel
  • lxml — быстрый HTML-парсер (BeautifulSoup может использовать его как backend)

Ваш блок импортов:

1import requests
2from bs4 import BeautifulSoup
3import pandas as pd

Шаг 2: отправьте HTTP-запрос к IMDb

Здесь большинство новичков натыкается на первую стену. IMDb блокирует запросы без корректного заголовка User-Agent — вы получите ошибку 403 Forbidden. Строка user-agent по умолчанию в Python Requests (python-requests/2.31.0) моментально попадает под фильтр.

1url = "https://www.imdb.com/chart/top/"
2headers = {
3    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
4    "Accept-Language": "en-US,en;q=0.9"
5}
6response = requests.get(url, headers=headers)
7if response.status_code != 200:
8    print(f"Не удалось получить страницу: \{response.status_code\}")
9else:
10    print("Страница успешно получена")

Заголовок Accept-Language тоже важен: без него IMDb может вернуть контент на другом языке в зависимости от геолокации вашего IP.

Шаг 3: разберите HTML с помощью BeautifulSoup

После того как HTML получен, создайте объект BeautifulSoup и начните искать нужные элементы. Откройте страницу IMDb Top 250 в Chrome, кликните правой кнопкой по названию фильма и выберите «Inspect», чтобы увидеть структуру HTML.

1soup = BeautifulSoup(response.text, "lxml")

На середину 2025 года страница Top 250 использует такие селекторы:

  • Контейнер фильма: li.ipc-metadata-list-summary-item
  • Название: h3.ipc-title__text
  • Год: span.cli-title-metadata-item (первый span)
  • Рейтинг: span.ipc-rating-star--rating

Предупреждение: классы с префиксом ipc- генерируются системой компонентов IMDb. Они были стабильны с редизайна в июне 2023 года, но никто не гарантирует, что они не изменятся снова.

Шаг 4: извлеките данные о фильме (название, год, рейтинг)

Здесь я отличаюсь от большинства туториалов: я добавляю обработку ошибок через try/except. Ни одно из конкурентных руководств, которые я проверял, этого не делает — именно поэтому их код молча ломается, когда меняется селектор.

1movies = []
2movie_items = soup.select("li.ipc-metadata-list-summary-item")
3for item in movie_items:
4    try:
5        title_tag = item.select_one("h3.ipc-title__text")
6        title = title_tag.text.strip() if title_tag else "N/A"
7        year_tag = item.select_one("span.cli-title-metadata-item")
8        year = year_tag.text.strip() if year_tag else "N/A"
9        rating_tag = item.select_one("span.ipc-rating-star--rating")
10        rating = rating_tag.text.strip() if rating_tag else "N/A"
11        movies.append({
12            "title": title,
13            "year": year,
14            "rating": rating
15        })
16    except Exception as e:
17        print(f"Ошибка при разборе фильма: \{e\}")
18        continue
19print(f"Извлечено {len(movies)} фильмов")

Шаг 5: сохраните в CSV или Excel с помощью Pandas

1df = pd.DataFrame(movies)
2df.to_csv("imdb_top_250.csv", index=False)
3df.to_excel("imdb_top_250.xlsx", index=False)
4print(df.head())

Пример вывода:

1                          title  year rating
20  1. The Shawshank Redemption  1994    9.3
31           2. The Godfather    1972    9.2
42     3. The Dark Knight        2008    9.0
53  4. The Godfather Part II     1974    9.0
64         5. 12 Angry Men       1957    9.0

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

Метод 2: трюк с JSON-LD — полностью обходите разбор HTML

Это техника, которую не покрывает ни одна конкурентная статья, и именно её я бы использовал для любого серьёзного проекта. IMDb встраивает структурированные данные в виде (JavaScript Object Notation for Linked Data) в теги <script type="application/ld+json"> на каждой странице. Эти данные следуют стандарту Schema.org, используются Google для расширенных результатов поиска и меняются намного реже, чем CSS-классы.

Production-grade инструмент Apify IMDb Scraper использует такой порядок приоритета извлечения: «JSON-LD > NEXT_DATA > DOM». Это и есть иерархия, которую я бы рекомендовал тоже.

Почему JSON-LD надёжнее CSS-селекторов

ПодходРаботает с JS-контентом?Устойчив к изменениям UI?СкоростьСложность
BeautifulSoup + CSS-селекторы❌ Нет⚠️ Хрупкий (имена классов меняются)БыстроНизкая
Извлечение JSON-LD✅ Да✅ Следует стандарту Schema.orgБыстроНизкая–средняя
Извлечение JSON из __NEXT_DATA__✅ Да✅ Довольно стабильноБыстроНизкая–средняя
Selenium / Playwright✅ Да⚠️ ХрупкийМедленноСредняя–высокая
Thunderbit (no-code, 2 клика)✅ Да (AI читает страницу)✅ AI автоматически подстраиваетсяБыстроНет

CSS-классы вроде ipc-metadata-list-summary-item генерируются системой React-компонентов IMDb и меняются при каждом редизайне. Схема JSON-LD отражает реальную модель данных, а не уровень отображения. Это как разница между чтением оглавления книги и попыткой понять главы по размеру шрифта.

css-selectors-vs-json-ld.webp

Пошагово: извлечение данных IMDb из JSON-LD

Шаг 1: получите страницу

Как и раньше — используйте requests с корректным заголовком User-Agent.

1import requests
2from bs4 import BeautifulSoup
3import json
4import pandas as pd
5url = "https://www.imdb.com/chart/top/"
6headers = {
7    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
8    "Accept-Language": "en-US,en;q=0.9"
9}
10response = requests.get(url, headers=headers)
11soup = BeautifulSoup(response.text, "lxml")

Шаг 2: найдите тег script с JSON-LD

1script_tag = soup.find("script", {"type": "application/ld+json"})
2if not script_tag:
3    print("На этой странице не найден JSON-LD")
4else:
5    data = json.loads(script_tag.string)
6    print(f"Найден JSON-LD с типом: {data.get('@type', 'unknown')}")

Шаг 3: разберите структурированные данные

На странице Top 250 JSON-LD содержит массив itemListElement со всеми 250 фильмами. Каждая запись включает позицию, имя, URL, aggregateRating, datePublished, genre, description, director и массивы actor.

1movies = []
2for item in data.get("itemListElement", []):
3    movie = item.get("item", {})
4    rating_info = movie.get("aggregateRating", {})
5    movies.append({
6        "rank": item.get("position"),
7        "title": movie.get("name"),
8        "url": movie.get("url"),
9        "rating": rating_info.get("ratingValue"),
10        "vote_count": rating_info.get("ratingCount"),
11        "date_published": movie.get("datePublished"),
12        "genre": ", ".join(movie.get("genre", [])),
13        "description": movie.get("description"),
14    })

Шаг 4: экспортируйте в CSV

1df = pd.DataFrame(movies)
2df.to_csv("imdb_top_250_json_ld.csv", index=False)
3print(df.head())

Пример вывода:

1   rank                      title                                     url  rating  vote_count date_published              genre
20     1  The Shawshank Redemption  https://www.imdb.com/title/tt0111161/     9.3     2900000     1994-10-14     Drama
31     2            The Godfather   https://www.imdb.com/title/tt0068646/     9.2     2000000     1972-03-24     Crime, Drama
42     3          The Dark Knight   https://www.imdb.com/title/tt0468569/     9.0     2800000     2008-07-18     Action, Crime, Drama

Все 250 фильмов. Чисто, структурировано, без плясок с CSS-селекторами. И поскольку эти данные следуют стандарту Schema.org, на который опирается Google в поисковой выдаче, они гораздо менее склонны к изменениям, чем визуальная разметка.

Бонус: __NEXT_DATA__ для страниц отдельных фильмов

Для более богатых данных со страниц конкретных тайтлов — хронометраж, полный актёрский состав, описание сюжета, изображения постеров — IMDb также встраивает JSON-объект __NEXT_DATA__. Это данные, которые React использует для гидратации страницы — убрать их нельзя, не сломав сайт.

1# На странице отдельного фильма вроде /title/tt0111161/
2next_data_tag = soup.find("script", {"id": "__NEXT_DATA__"})
3if next_data_tag:
4    next_data = json.loads(next_data_tag.string)
5    above_fold = next_data["props"]["pageProps"]["aboveTheFoldData"]
6    title = above_fold["titleText"]["text"]
7    year = above_fold["releaseYear"]["year"]
8    rating = above_fold["ratingsSummary"]["aggregateRating"]
9    runtime_seconds = above_fold.get("runtime", {}).get("seconds", 0)
10    genres = [g["text"] for g in above_fold["genres"]["genres"]]
11    plot = above_fold["plot"]["plotText"]["plainText"]

Используйте JSON-LD для страниц списков и __NEXT_DATA__ для страниц отдельных тайтлов. Это и есть production-grade подход.

Почему ваш IMDb-скрейпер всё время ломается — и как это исправить

Это самая часто обсуждаемая проблема во всех форумах по парсингу IMDb, которые я проверял. Пользователи пишут: «Some of the code broke because of UI changes» и «Not working in 2024!» — а в ответ обычно тишина или совет «попробуйте Selenium».

Корневая причина — постоянная миграция IMDb на React/Next.js frontend. Вот хронология крупных ломающих изменений:

| Дата | Что изменилось | Что сломалось | |---|---|---|---| | Ноябрь 2022 | Редизайн Name Pages | Старые скрейперы страниц имён | | Июнь 2023 | Редизайн страницы Top 250 | Все селекторы td.titleColumn / td.ratingColumn | | Апрель 2023 | Редизайн подстраниц тайтлов | Скрейперы биографий, наград, новостей | | Октябрь 2023 | Редизайн Advanced Search | Скрейперы на основе поиска | | Июнь 2025 | Редизайн /reference pages | Библиотека Cinemagoer (большинство парсеров) |

Это примерно одно крупное ломающие изменение каждые 6–12 месяцев. Если ваш скрейпер зависит от CSS-классов, вы бежите по беговой дорожке.

Частые ошибки и как их исправить

Пустые результаты / ошибки NoneType

Самая распространённая ошибка. Вы увидите AttributeError: 'NoneType' object has no attribute 'text'. Это означает, что BeautifulSoup не нашёл элемент, который вы искали, — обычно потому, что изменилось имя CSS-класса или контент рендерится JavaScript’ом.

Исправление: переключитесь на извлечение JSON-LD (Метод 2 выше). Данные уже есть в начальном HTML-ответе, JavaScript не нужен.

403 Forbidden

IMDb использует для обнаружения и блокировки ботов. Триггер №1 — отсутствующий или явно фальшивый заголовок User-Agent. Это задокументировано в open-source проектах и , где сотрудник IMDb признал проблему.

Исправление: всегда добавляйте реалистичную строку User-Agent браузера и заголовок Accept-Language: en-US. Используйте requests.Session() для повторного использования соединений.

Возвращается только 25 результатов

Страницы поиска IMDb и списки «Most Popular» используют ленивую загрузку — сначала отображается только около 25 результатов, а остальные подгружаются через AJAX по мере прокрутки.

Исправление: используйте пагинацию через параметр URL (см. следующий раздел) или перейдите на страницу Top 250, которая загружается целиком одним ответом.

Селекторы внезапно перестали работать

Старые селекторы, которые больше не работают: td.titleColumn, td.ratingColumn, .lister-item-header, .inline-block.ratings-imdb-rating. Если ваш код использует что-то из этого, он сломан.

Исправление: предпочитайте атрибуты data-testid (например, h1[data-testid="hero-title-block__title"]) вместо автоматически сгенерированных имён классов. А ещё лучше — используйте JSON-LD.

Каркас принятия решения: краткосрочные и долгосрочные фиксы

  • Быстрый фикс: оборачивайте каждый селектор в try/except, проверяйте HTTP-коды ответа, логируйте ошибки вместо падения
  • Среднесрочный фикс: переходите с CSS-селекторов на извлечение JSON-LD (Метод 2)
  • Долгосрочный фикс: используйте для крупномасштабного анализа или инструмент вроде , который использует AI, чтобы каждый раз заново считывать структуру страницы — без селекторов, которые нужно поддерживать, AI автоматически подстраивается под изменения верстки

За пределами лимита в 25 результатов: пагинация IMDb и большие датасеты

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

Страницы, которым не нужна пагинация

Хорошая новость: страница Top 250 загружает все 250 фильмов одним серверным ответом. И JSON-LD, и __NEXT_DATA__ содержат полный датасет. Пагинация не нужна.

Как работает пагинация поиска IMDb

Страницы поиска IMDb используют параметр URL start=, увеличивая его на 50:

1https://www.imdb.com/search/title/?groups=top_1000&start=1
2https://www.imdb.com/search/title/?groups=top_1000&start=51
3https://www.imdb.com/search/title/?groups=top_1000&start=101

Вот цикл на Python, который проходит по страницам результатов:

1import time
2all_movies = []
3for start in range(1, 1001, 50):  # Переход по страницам top 1000
4    url = f"https://www.imdb.com/search/title/?groups=top_1000&start=\{start\}"
5    response = requests.get(url, headers=headers)
6    if response.status_code != 200:
7        print(f"Ошибка на start=\{start\}: \{response.status_code\}")
8        break
9    soup = BeautifulSoup(response.text, "lxml")
10    # Извлекайте фильмы выбранным методом
11    # ...
12    print(f"Скрапинг страницы, начинающейся с \{start\}")
13    time.sleep(3)  # Будьте аккуратны — IMDb блокирует после ~50 быстрых запросов

Этот time.sleep(3) важен. По сообщениям сообщества, IMDb начинает блокировать IP примерно после 50 быстрых запросов. Случайная задержка 2–5 секунд — хорошая практика.

Когда скрапинг вообще не нужен: официальные bulk-датасеты IMDb

Для действительно больших задач IMDb предоставляет 7 бесплатных TSV-файлов на , которые обновляются ежедневно:

ФайлСодержимоеРазмер
title.basics.tsv.gzНазвания, типы, жанры, хронометраж, год~800 MB
title.ratings.tsv.gzСредний рейтинг, количество голосов~25 MB
title.crew.tsv.gzРежиссёры, сценаристы~300 MB
title.principals.tsv.gzГлавные актёры и команда~2 GB
title.akas.tsv.gzАльтернативные названия по регионам~1.5 GB
title.episode.tsv.gzДанные по ТВ-эпизодам~200 MB
name.basics.tsv.gzЛюди: имя, год рождения, известные тайтлы~700 MB

Загрузить их в Pandas просто:

1ratings = pd.read_csv("title.ratings.tsv.gz", sep="\t", compression="gzip")
2basics = pd.read_csv("title.basics.tsv.gz", sep="\t", compression="gzip", low_memory=False)
3# Объединяем по tconst (IMDb title ID)
4merged = basics.merge(ratings, on="tconst")
5top_movies = merged[merged["titleType"] == "movie"].nlargest(250, "averageRating")

Эти датасеты охватывают 26+ миллионов тайтлов. Никакой пагинации, никаких селекторов, никаких ошибок 403. Лицензия — только для личного и некоммерческого использования: публиковать повторно или перепродавать данные нельзя.

No-code альтернатива: Thunderbit сам справляется с пагинацией

Для читателей, которым нужны данные IMDb со страницами пагинации, но которые не хотят писать логику пагинации вручную, нативно поддерживает и пагинацию по клику, и бесконечную прокрутку. Вы говорите ему, что скрапить, а он делает остальное — включая прокрутку лениво загружаемого контента.

Парсинг IMDb на Python: полный рабочий код, готовый к копированию

Ниже — два самодостаточных скрипта, которые можно запустить прямо сейчас.

Скрипт A: метод BeautifulSoup (CSS-селекторы)

1import requests
2from bs4 import BeautifulSoup
3import pandas as pd
4url = "https://www.imdb.com/chart/top/"
5headers = {
6    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
7    "Accept-Language": "en-US,en;q=0.9"
8}
9response = requests.get(url, headers=headers)
10if response.status_code != 200:
11    print(f"Ошибка: \{response.status_code\}")
12    exit()
13soup = BeautifulSoup(response.text, "lxml")
14movie_items = soup.select("li.ipc-metadata-list-summary-item")
15movies = []
16for item in movie_items:
17    try:
18        title = item.select_one("h3.ipc-title__text")
19        year = item.select_one("span.cli-title-metadata-item")
20        rating = item.select_one("span.ipc-rating-star--rating")
21        movies.append({
22            "title": title.text.strip() if title else "N/A",
23            "year": year.text.strip() if year else "N/A",
24            "rating": rating.text.strip() if rating else "N/A",
25        })
26    except Exception as e:
27        print(f"Пропускаю фильм из-за ошибки: \{e\}")
28df = pd.DataFrame(movies)
29df.to_csv("imdb_top250_bs4.csv", index=False)
30print(f"Сохранено фильмов: {len(df)}")
31print(df.head())

Скрипт B: метод JSON-LD (рекомендуется)

1import requests
2from bs4 import BeautifulSoup
3import json
4import pandas as pd
5url = "https://www.imdb.com/chart/top/"
6headers = {
7    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
8    "Accept-Language": "en-US,en;q=0.9"
9}
10response = requests.get(url, headers=headers)
11if response.status_code != 200:
12    print(f"Ошибка: \{response.status_code\}")
13    exit()
14soup = BeautifulSoup(response.text, "lxml")
15script_tag = soup.find("script", {"type": "application/ld+json"})
16if not script_tag:
17    print("JSON-LD данные не найдены")
18    exit()
19data = json.loads(script_tag.string)
20movies = []
21for item in data.get("itemListElement", []):
22    movie = item.get("item", {})
23    rating_info = movie.get("aggregateRating", {})
24    directors = movie.get("director", [])
25    director_names = ", ".join(
26        d.get("name", "") for d in (directors if isinstance(directors, list) else [directors])
27    )
28    movies.append({
29        "rank": item.get("position"),
30        "title": movie.get("name"),
31        "url": movie.get("url"),
32        "rating": rating_info.get("ratingValue"),
33        "votes": rating_info.get("ratingCount"),
34        "year": movie.get("datePublished", "")[:4],
35        "genre": ", ".join(movie.get("genre", [])),
36        "director": director_names,
37        "description": movie.get("description"),
38    })
39df = pd.DataFrame(movies)
40df.to_csv("imdb_top250_jsonld.csv", index=False)
41print(f"Сохранено фильмов: {len(df)}")
42print(df.head())

Оба скрипта включают обработку ошибок и создают аккуратный CSV-вывод. Скрипт B даёт больше данных — режиссёра, описание, URL — и лучше переживает изменения верстки.

Как спарсить IMDb без кода (с помощью Thunderbit)

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

Вот как получить те же данные с помощью :

Перед началом:

  • Сложность: Начальный уровень
  • Время: ~2 минуты
  • Что понадобится: браузер Chrome, (бесплатный тариф подходит)

Шаг 1: откройте страницу IMDb, которую хотите спарсить. Откройте IMDb Top 250 (или любой другой список/страницу поиска IMDb) в Chrome.

Шаг 2: нажмите «AI Suggest Fields» в боковой панели Thunderbit. AI просканирует страницу и предложит столбцы — обычно Title, Year, Rating, Genre и ещё несколько, в зависимости от страницы. Вы увидите предварительную таблицу с предложенными полями.

Шаг 3: при необходимости скорректируйте поля. Удалите лишние столбцы или добавьте свои, нажав «+ Add Column» и описав, что хотите получить, простым английским (например, «Director name» или «Number of votes»).

Шаг 4: нажмите «Scrape». Thunderbit извлечёт данные. Для страниц с бесконечной прокруткой или пагинацией он автоматически обработает прокрутку.

Шаг 5: экспортируйте. Нажмите кнопку экспорта и выберите формат — Excel, Google Sheets, CSV, Airtable или Notion. Данные попадут в нужное место за секунды.

Ключевое преимущество здесь не только в удобстве — Thunderbit’s AI каждый раз заново читает структуру страницы. Когда IMDb меняет разметку, AI адаптируется. Никаких селекторов для обновления, никакого кода для исправления. Для тех, кого уже подводил сломанный скрейпер в 2 часа ночи перед дедлайном, это дорогого стоит.

Thunderbit также поддерживает парсинг подстраниц — можно перейти в карточку каждого фильма и обогатить таблицу актёрским составом, режиссёром, хронометражем и другими полями, которых нет на списковой странице. Если хотите увидеть это в действии, загляните на .

Законно ли парсить IMDb? Что нужно знать

Пользователи прямо спрашивают об этом на форумах: «Is something like this legal?… IMDb does not want people scraping their website.» Вопрос справедливый, и ни одна конкурентная статья его не разбирает.

robots.txt IMDb: страница Top 250 (/chart/top/), отдельные страницы тайтлов (/title/ttXXXXXXX/) и страницы имён (/name/nmXXXXXXX/) НЕ заблокированы в robots.txt. Заблокированные пути включают /find, /_json/*, /search/name-text, /user/ur*/ratings и различные AJAX-endpoint’ы. Директива Crawl-delay не указана.

Условия использования IMDb: соответствующий пункт гласит: «Вы не можете использовать data mining, robots, screen scraping или аналогичные инструменты сбора и извлечения данных на этом сайте без нашего прямого письменного согласия». Дополнительный пункт запрещает перепродажу или коммерческое использование спарсенных данных.

Что это значит на практике: недавние судебные решения 2024 года (Meta v. Bright Data, X Corp v. Bright Data) пришли к выводу, что Terms of Service могут не связывать пользователей, которые никогда с ними не соглашались — если вы парсите общедоступные данные без логина, исполнимость ToS спорна. Но правовая зона здесь всё ещё меняется.

Безопасные альтернативы: прямо разрешены для личного и некоммерческого использования. API TMDb довольно лоялен и доступен с бесплатным ключом. Оба варианта хороши, если хотите оставаться в безопасной зоне.

Практический совет: если всё же парсите, используйте уважительный темп обхода (time.sleep(3) между запросами), задавайте корректные заголовки и не обращайтесь к путям, заблокированным в robots.txt. Для коммерческих проектов проконсультируйтесь с юристом или используйте официальные датасеты/API.

Мы подробно разобрали в блоге Thunderbit.

Итог: выберите правильный способ парсить IMDb с помощью Python

Коротко:

  • BeautifulSoup + CSS-селекторы: хорошо подходит для изучения основ. Ожидайте, что он будет ломаться каждые 6–12 месяцев. Всегда добавляйте обработку ошибок.
  • Извлечение JSON-LD: подход, который я бы рекомендовал для любого продолжающегося Python-проекта. Следует стандарту Schema.org, меняется гораздо реже, чем CSS-классы, и даёт чистые структурированные данные без рендеринга JavaScript.
  • JSON __NEXT_DATA__: используйте как дополнение для более богатых данных на страницах отдельных тайтлов (хронометраж, полный актёрский состав, сюжет, изображения постеров).
  • Официальные датасеты IMDb: лучший выбор для крупномасштабного анализа. 26M+ тайтлов, ежедневные обновления, скрапинг не нужен. Только личное/некоммерческое использование.
  • : лучший выбор для тех, кто не пишет код, или для тех, кому нужны данные быстро и без поддержки скриптов. AI подстраивается под изменения верстки, поддерживает пагинацию, экспортирует в Excel/Sheets/Airtable/Notion.

Добавьте это руководство в закладки — я обновлю его, когда структура IMDb в следующий раз изменится. А если хотите вообще обойтись без кода, и посмотрите, как быстро можно перейти от страницы IMDb к аккуратной таблице. Если вы работаете и с другими сайтами, наш гайд по описывает более широкий рабочий процесс.

Попробуйте AI Web Scraper для IMDb и не только

Часто задаваемые вопросы

Законно ли парсить IMDb?

Условия использования IMDb запрещают скрапинг без согласия, но исполнимость ToS в отношении общедоступных данных после недавних судебных решений 2024 года юридически спорна. Самые безопасные варианты — (для личного и некоммерческого использования) или API TMDb (бесплатный ключ). Если всё же парсите, соблюдайте robots.txt, делайте разумные задержки между запросами и не заходите на заблокированные пути. Для коммерческого использования проконсультируйтесь с юристом.

Почему мой IMDb-скрейпер возвращает пустые результаты?

Почти всегда причина в устаревших CSS-селекторах — классы вроде td.titleColumn и td.ratingColumn не существуют с июня 2023 года. Решение — перейти на извлечение JSON-LD (разобрать тег <script type="application/ld+json">) или обновить селекторы до текущих классов с префиксом ipc-. Также проверьте, что вы передаёте корректный заголовок User-Agent, потому что его отсутствие вызывает ошибку 403, которая может выглядеть как пустой результат.

Как спарсить больше 25 результатов с IMDb?

Страница Top 250 загружает все 250 фильмов одним ответом — пагинация не нужна. Для результатов поиска используйте параметр start= в URL (увеличивается на 50), чтобы переходить между страницами. Например: start=1, start=51, start=101. Добавьте time.sleep(3) между запросами, чтобы не получить блокировку. Либо используйте официальные датасеты IMDb на , где 26M+ тайтлов и пагинация вообще не нужна.

Что такое __NEXT_DATA__ и зачем использовать его для парсинга IMDb?

__NEXT_DATA__ — это JSON-объект, встроенный в тег <script id="__NEXT_DATA__"> на страницах IMDb на React/Next.js. Он содержит полные структурированные данные, которые React использует для рендеринга страницы — названия, рейтинги, актёров, жанры, хронометраж и многое другое. Поскольку он отражает базовую модель данных, а не визуальную верстку, он устойчивее к редизайнам интерфейса, чем CSS-селекторы. Используйте его вместе с JSON-LD для максимально надёжного извлечения.

Можно ли парсить IMDb без программирования?

Да. Два основных варианта: (1) скачать — 7 TSV-файлов, покрывающих 26M+ тайтлов, ежедневно обновляемых и бесплатных для некоммерческого использования. (2) использовать , который читает страницу IMDb, автоматически предлагает поля извлечения и экспортирует в Excel, Google Sheets или CSV в два клика — без кода и без необходимости поддерживать селекторы.

Подробнее

Попробуй Thunderbit

Собирай лиды и другие данные всего в 2 клика. На базе AI.

Получить Thunderbit Это бесплатно
Извлекай данные с помощью AI
Легко передавай данные в Google Sheets, Airtable или Notion
PRODUCT HUNT#1 Product of the Week