"파이썬으로 IMDb 스크래핑"을 검색해 본 적 있다면 한 가지를 금방 눈치챘을 거예요. 튜토리얼 대부분이 이미 망가져 있다는 사실이요. "살짝 낡았다" 수준이 아니라, 결과는 0개에 NoneType 오류만 쏟아지는 수준예요.
지난 몇 주 동안 GeeksforGeeks, Medium, freeCodeCamp, Kaggle 노트북 등 손에 잡히는 주요 IMDb 스크래핑 튜토리얼을 죄다 돌려 봤어요. IMDb 스크래퍼로 태그된 214개 이상의 공개 GitHub 저장소 중 상당수가, IMDb가 Top 250 페이지를 갈아엎은 2023년 6월 이후로는 사라진 CSS 선택자(td.titleColumn, td.ratingColumn)를 여전히 참조하고 있었어요. 결과는요? 왜 빈 결과만 나오느냐고 묻는 개발자로 가득 찬 포럼, 그리고 Cinemagoer 같은 인기 라이브러리 메인테이너가 "파서를 전부 고치는 것 말고는 우리가 할 수 있는 게 없다"고 인정하는 상황이었죠. 이 글에서는 지금 실제로 돌아가는 파이썬 방법 두 가지, 페이지네이션과 흔한 오류 대처법, 파이썬이 아예 답이 아닌 경우, 그리고 스크래퍼가 금방 쓸모없어지지 않게 미리 대비하는 법까지 다뤄요.
파이썬으로 IMDb를 스크래핑한다는 건 무슨 뜻일까요?
웹 스크래핑은 웹페이지에서 데이터를 프로그램으로 뽑아내는 작업이에요. 손으로 복사·붙여넣기 하는 대신, 그 일을 대신할 스크립트를 짜는 거죠. "IMDb를 스크래핑한다"는 건 파이썬으로 IMDb 페이지에서 제목·평점·장르·출연진·상영 시간·투표 수 같은 구조화된 영화 데이터를 가져온다는 뜻예요.
이 작업에 흔히 쓰는 파이썬 스택은 라이브러리 세 개로 짜여요. requests가 웹페이지를 가져오고, BeautifulSoup가 HTML을 파싱해 데이터를 찾고, pandas가 결과를 정리하고 내보내요. 자바스크립트 렌더링이 필요한 페이지엔 Selenium이나 Playwright를 쓰는 튜토리얼도 있는데, 곧 보겠지만 더 빠른 길이 있어요.
한 가지 미리 짚을 점. 이 글의 내용은 2025년 중반 기준 IMDb 페이지 구조로 검증했어요. IMDb가 대략 6~12개월마다 구조를 바꾸니, 2027년에 이 글을 읽는다면 일부 선택자가 달라졌을 수 있어요. (그 대처법도 같이 설명할게요.)
왜 파이썬으로 IMDb를 스크래핑할까요? 실제 활용 사례
코드를 한 줄 짜기 전에 먼저 답해야 할 질문이 있어요. IMDb 데이터로 대체 뭘 할 건가? 답은 당신이 누구냐에 따라 달라져요.
IMDb 리뷰 데이터셋은 전 세계에서 가장 널리 쓰이는 NLP 벤치마크 중 하나예요. Maas 외(2011)의 기반 논문은 5,706회 인용됐고, 이 데이터셋은 TensorFlow·Keras·PyTorch에 기본 탑재돼 있어요. Hugging Face에선 stanfordnlp/imdb 데이터셋이 월 213,321회 다운로드되며 1,500개 넘는 모델 학습에 쓰였어요. 머신러닝을 한다면 이미 IMDb 데이터를 손에 익히고 있을 가능성이 높다는 얘기죠.
물론 활용은 학계에만 머물지 않아요.
| 활용 사례 | 대상 | 필요한 데이터 필드 |
|---|---|---|
| 영화 추천 엔진 | 데이터 과학자, 취미 개발자 | 제목, 장르, 평점, 출연진 |
| 스트리밍 플랫폼 콘텐츠 전략 | 제품/콘텐츠 팀 | 평점, 투표 수, 개봉 연도, 장르 |
| 감성 분석 / NLP 학습 | ML 연구자, 학생 | 리뷰, 평점 |
| 경쟁 콘텐츠 분석 | 엔터테인먼트 업계 분석가 | 흥행 성적, 개봉일, 평점 추이 |
| 영화 관광 연구 | 관광청, 여행사 | 촬영지, 인기도 지표 |
| 학술 연구 | 대학 연구자 | 구조화된 영화 메타데이터 전반 |
영화 관광 시장만 해도 2025년 전 세계 기준 약 660억 달러(약 91조 원) 규모로 추정돼요. Netflix는 2024년 콘텐츠에 170억 달러 이상을 썼고, 시청 활동의 80%가 개인화 추천에서 나왔어요. IMDb 데이터가 여러 산업의 실제 의사결정에 쓰인다는 뜻이에요.
코드를 짜기 전에 알아 둘 IMDb 데이터 확보 경로
이 부분을 대부분의 튜토리얼이 통째로 건너뛰어요. 곧장 pip install beautifulsoup4부터 시작하면서, 지금 상황에 파이썬 스크래핑이 정말 맞는지는 묻지 않거든요.
선택지를 전부 펼쳐 보면 이래요.
| 방법 | 적합한 경우 | 장점 | 단점 |
|---|---|---|---|
| Python + BeautifulSoup | 학습, 맞춤 추출 | 완전한 제어, 유연함 | 선택자가 취약하고 자주 깨짐 |
JSON-LD / __NEXT_DATA__ 추출 | 안정성을 원하는 개발자 | JS 콘텐츠 처리, 더 견고함 | JSON 구조를 이해해야 함 |
| IMDb 공식 데이터셋 | 대규모 분석, 학술용 | 합법적, 완전한 데이터, 2,600만+ 타이틀, 일일 업데이트 | TSV 형식, 리뷰/이미지 없음 |
| Cinemagoer (IMDbPY) 라이브러리 | 타이틀별 프로그램 조회 | 파이썬다운 API, 풍부한 필드 | 열린 이슈 88개, 마지막 릴리스 2023년 5월 |
| TMDb API | 영화 메타데이터 + 이미지 | 무료 API 키, JSON, 문서화 잘 됨 | 소스가 다름(IMDb 평점 아님) |
| Thunderbit (노코드) | 비개발자, 빠른 내보내기 | 2번 클릭 스크래핑, AI가 필드 제안, Excel/Sheets로 내보내기 | 대량 스크래핑은 크레딧 기반 |
몇 가지 덧붙일게요. Cinemagoer는 2023년 5월 이후 PyPI 릴리스가 없고, IMDb의 2025년 6월 재설계 뒤로 파서 대부분이 깨졌어요. 지금 운영 환경에 쓰는 건 권하지 않아요. TMDb는 훌륭하지만 IMDb가 아닌 자체 평점 체계를 써요. 그리고 IMDb 공식 엔터프라이즈 API는 AWS Data Exchange를 통해 연 5만 달러 이상이 들어, 대부분에겐 현실적인 선택지가 아니에요.
코드를 아예 쓰기 싫다면, Thunderbit의 AI 웹 스크래퍼가 IMDb 페이지를 읽고 추출 필드(제목·평점·연도·장르 등)를 자동으로 제안한 뒤 Excel·Google Sheets·Airtable·Notion으로 클릭 두 번에 내보내 줘요. IMDb가 레이아웃을 바꿔도 AI가 알아서 적응하니 관리할 선택자가 없어요. 이건 뒤에서 더 자세히 다룰게요.
자, 이제 파이썬으로 직접 짜고 싶은 분들을 위해 실제로 돌아가는 방법 두 가지를 보여 드릴게요.
방법 1: BeautifulSoup으로 IMDb 스크래핑하기 (전통 방식)
대부분의 튜토리얼에서 보이는 고전적인 방식이에요. 작동은 하지만, 먼저 분명히 해 둘게요. 오늘 다룰 방법 중 가장 취약해요. IMDb의 CSS 클래스 이름은 자동 생성되고, 재설계 때마다 바뀌거든요. 그래도 웹 스크래핑 기초를 익히기엔 이만한 게 없어요.
STEP 1: 파이썬 라이브러리 설치 및 import
패키지 네 개가 필요해요.
pip install requests beautifulsoup4 pandas lxml
각각의 역할은 이래요.
requests— 웹페이지를 가져오기 위해 HTTP 요청을 보냄beautifulsoup4— HTML을 파싱해 특정 요소를 찾을 수 있게 함pandas— 추출한 데이터를 표로 정리하고 CSV/Excel로 내보냄lxml— 빠른 HTML 파서(BeautifulSoup의 백엔드로 사용 가능)
import 코드는 이래요.
import requests
from bs4 import BeautifulSoup
import pandas as pd
STEP 2: IMDb에 HTTP 요청 보내기
초보자 대부분이 여기서 첫 벽에 부딪혀요. IMDb는 제대로 된 User-Agent 헤더가 없는 요청을 막아요. 그러면 403 Forbidden이 떨어져요. Python Requests의 기본 user-agent 문자열(python-requests/2.31.0)은 바로 차단돼요.
url = "https://www.imdb.com/chart/top/"
headers = {
"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",
"Accept-Language": "en-US,en;q=0.9"
}
response = requests.get(url, headers=headers)
if response.status_code != 200:
print(f"페이지 가져오기 실패: {response.status_code}")
else:
print("페이지를 성공적으로 가져왔습니다")
Accept-Language 헤더도 중요해요. 이게 없으면 IMDb가 IP의 지리 위치에 따라 다른 언어로 콘텐츠를 돌려줄 수 있어요.
STEP 3: BeautifulSoup으로 HTML 파싱하기
HTML을 받았으면 BeautifulSoup 객체를 만들고 원하는 요소를 찾기 시작하면 돼요. Chrome에서 IMDb Top 250 페이지를 열고, 영화 제목을 우클릭한 뒤 "검사"를 눌러 HTML 구조를 살펴보세요.
soup = 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년 6월 재설계 이후 안정적으로 유지되곤 있지만, 다시 안 바뀐다는 보장은 없어요.
STEP 4: 영화 데이터 추출하기(제목, 연도, 평점)
여기선 많은 튜토리얼과 달리 try/except 오류 처리를 넣었어요. 제가 검토한 경쟁 가이드 대부분이 이걸 빠뜨렸는데, 선택자가 바뀌었을 때 코드가 조용히 깨지는 이유가 바로 그거예요.
movies = []
movie_items = soup.select("li.ipc-metadata-list-summary-item")
for item in movie_items:
try:
title_tag = item.select_one("h3.ipc-title__text")
title = title_tag.text.strip() if title_tag else "N/A"
year_tag = item.select_one("span.cli-title-metadata-item")
year = year_tag.text.strip() if year_tag else "N/A"
rating_tag = item.select_one("span.ipc-rating-star--rating")
rating = rating_tag.text.strip() if rating_tag else "N/A"
movies.append({
"title": title,
"year": year,
"rating": rating
})
except Exception as e:
print(f"영화 파싱 오류: {e}")
continue
print(f"{len(movies)}개의 영화를 추출했습니다")
STEP 5: Pandas로 CSV 또는 Excel에 저장하기
df = pd.DataFrame(movies)
df.to_csv("imdb_top_250.csv", index=False)
df.to_excel("imdb_top_250.xlsx", index=False)
print(df.head())
출력 예시는 이래요.
title year rating
0 1. 쇼생크 탈출 1994 9.3
1 2. 대부 1972 9.2
2 3. 다크 나이트 2008 9.0
3 4. 대부 2 1974 9.0
4 5. 12인의 성난 사람들 1957 9.0
작동은 해요. 하지만 CSS 선택자에 목줄을 매달고 있어서 언제든 끊길 수 있어요. 그래서 제가 진짜 추천하는 건 다음 방법예요.
방법 2: JSON-LD 트릭 — HTML 파싱을 통째로 건너뛰기
경쟁 기사에서 거의 안 다루는 기법이고, 진지한 프로젝트라면 제가 택할 방식이에요. IMDb는 모든 페이지의 <script type="application/ld+json"> 태그 안에 JSON-LD(Linked Data용 JavaScript Object Notation) 형식의 구조화 데이터를 넣어요. 이 데이터는 Schema.org 표준을 따르고, Google 리치 검색 결과에도 쓰이며, CSS 클래스 이름보다 훨씬 덜 바뀌어요.
프로덕션급 도구인 Apify IMDb Scraper도 추출 우선순위를 "JSON-LD > NEXT_DATA > DOM" 순으로 둬요. 저도 같은 순서를 추천해요.
JSON-LD가 CSS 선택자보다 안정적인 이유
| 접근 방식 | JS 콘텐츠 처리 가능? | UI 변경에 강한가? | 속도 | 복잡도 |
|---|---|---|---|---|
| BeautifulSoup + CSS 선택자 | ❌ 아니요 | ⚠️ 취약함(클래스명이 바뀜) | 빠름 | 낮음 |
| JSON-LD 추출 | ✅ 예 | ✅ Schema.org 표준을 따름 | 빠름 | 낮음~중간 |
__NEXT_DATA__ JSON 추출 | ✅ 예 | ✅ 비교적 안정적 | 빠름 | 낮음~중간 |
| Selenium / Playwright | ✅ 예 | ⚠️ 취약함 | 느림 | 중간~높음 |
| Thunderbit (노코드, 2번 클릭) | ✅ 예(AI가 페이지를 읽음) | ✅ AI가 자동으로 적응함 | 빠름 | 없음 |
ipc-metadata-list-summary-item 같은 CSS 클래스명은 IMDb의 React 컴포넌트 시스템이 자동 생성한 값이라 재설계 때마다 바뀌어요. 반면 JSON-LD 스키마는 표시 계층이 아니라 실제 데이터 모델을 나타내요. 책의 목차를 읽는 것과, 글자 크기만 보고 장을 짐작하려는 것의 차이라고 보면 돼요.

단계별: JSON-LD에서 IMDb 데이터 추출하기
STEP 1: 페이지 가져오기
앞과 똑같이, 제대로 된 User-Agent 헤더와 함께 requests를 써요.
import requests
from bs4 import BeautifulSoup
import json
import pandas as pd
url = "https://www.imdb.com/chart/top/"
headers = {
"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",
"Accept-Language": "en-US,en;q=0.9"
}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, "lxml")
STEP 2: JSON-LD script 태그 찾기
script_tag = soup.find("script", {"type": "application/ld+json"})
if not script_tag:
print("이 페이지에서 JSON-LD를 찾지 못했습니다")
else:
data = json.loads(script_tag.string)
print(f"유형이 {data.get('@type', 'unknown')}인 JSON-LD를 찾았습니다")
STEP 3: 구조화 데이터 파싱하기
Top 250 페이지의 JSON-LD에는 250개 영화가 모두 담긴 itemListElement 배열이 있어요. 각 항목엔 순위, 이름, URL, aggregateRating, datePublished, genre, description, director, actor 배열이 들어 있어요.
movies = []
for item in data.get("itemListElement", []):
movie = item.get("item", {})
rating_info = movie.get("aggregateRating", {})
movies.append({
"rank": item.get("position"),
"title": movie.get("name"),
"url": movie.get("url"),
"rating": rating_info.get("ratingValue"),
"vote_count": rating_info.get("ratingCount"),
"date_published": movie.get("datePublished"),
"genre": ", ".join(movie.get("genre", [])),
"description": movie.get("description"),
})
STEP 4: CSV로 내보내기
df = pd.DataFrame(movies)
df.to_csv("imdb_top_250_json_ld.csv", index=False)
print(df.head())
출력 예시:
rank title url rating vote_count date_published genre
0 1 쇼생크 탈출 https://www.imdb.com/title/tt0111161/ 9.3 2900000 1994-10-14 드라마
1 2 대부 https://www.imdb.com/title/tt0068646/ 9.2 2000000 1972-03-24 범죄, 드라마
2 3 다크 나이트 https://www.imdb.com/title/tt0468569/ 9.0 2800000 2008-07-18 액션, 범죄, 드라마
250개 영화가 전부 나와요. 깔끔하고 구조화돼 있고, CSS 선택자 잡기 게임도 없어요. 게다가 이 데이터는 Google 검색 결과에 쓰이는 Schema.org 표준을 따르니, 화면 레이아웃보다 훨씬 덜 바뀌어요.
보너스: 개별 영화 페이지의 __NEXT_DATA__
개별 타이틀 페이지에서 더 풍부한 데이터(상영 시간, 전체 출연진, 줄거리 요약, 포스터 이미지 등)가 필요하다면, IMDb는 __NEXT_DATA__ JSON 객체도 함께 넣어요. React가 페이지를 하이드레이션할 때 쓰는 데이터라, 사이트가 통째로 망가지지 않는 한 사라질 수 없어요.
# /title/tt0111161/ 같은 개별 영화 페이지에서
next_data_tag = soup.find("script", {"id": "__NEXT_DATA__"})
if next_data_tag:
next_data = json.loads(next_data_tag.string)
above_fold = next_data["props"]["pageProps"]["aboveTheFoldData"]
title = above_fold["titleText"]["text"]
year = above_fold["releaseYear"]["year"]
rating = above_fold["ratingsSummary"]["aggregateRating"]
runtime_seconds = above_fold.get("runtime", {}).get("seconds", 0)
genres = [g["text"] for g in above_fold["genres"]["genres"]]
plot = above_fold["plot"]["plotText"]["plainText"]
차트·목록 페이지엔 JSON-LD를, 개별 타이틀 페이지엔 __NEXT_DATA__를 쓰세요. 그게 프로덕션급 접근법예요.
왜 IMDb 스크래퍼는 자꾸 깨질까요? 그리고 어떻게 고칠까요?
제가 들여다본 IMDb 스크래핑 포럼마다 단골로 나오는 불만이 바로 이거예요. 사람들은 이렇게 써요. "UI 바뀌면서 코드 일부가 깨졌어요", "2024년엔 안 돌아가요!" 그리고 돌아오는 건 대개 침묵이거나 "Selenium 써보세요"뿐이죠.
근본 원인은 IMDb가 React/Next.js 프런트엔드로 계속 옮겨 가고 있기 때문이에요. 주요 깨짐 변화의 타임라인은 이래요.
| 날짜 | 변경 내용 | 깨진 것 |
|---|---|---|
| 2022년 11월 | Name Pages 재설계 | 기존 이름 페이지 스크래퍼 |
| 2023년 6월 | Top 250 페이지 재설계 | 모든 td.titleColumn / td.ratingColumn 선택자 |
| 2023년 4월 | 타이틀 하위 페이지 재설계 | 소개, 수상, 뉴스 스크래퍼 |
| 2023년 10월 | 고급 검색 재설계 | 검색 기반 스크래퍼 |
| 2025년 6월 | /reference 페이지 재설계 | Cinemagoer 라이브러리 (대부분의 파서) |
대략 6~12개월에 한 번씩 큰 변경이 닥치는 셈이에요. 스크래퍼가 CSS 클래스명에 기대고 있다면, 멈추지 않는 러닝머신 위에 올라탄 거나 다름없어요.
흔한 오류와 해결법
빈 결과 / NoneType 오류
가장 흔한 오류예요. AttributeError: 'NoneType' object has no attribute 'text'가 떠요. BeautifulSoup이 찾는 요소를 못 찾았다는 뜻으로, 보통 CSS 클래스명이 바뀌었거나 콘텐츠가 자바스크립트로 렌더링되기 때문이에요.
해결: JSON-LD 추출(위 방법 2)로 갈아타세요. 데이터가 초기 HTML 응답 안에 들어 있어서 자바스크립트가 필요 없어요.
403 Forbidden
IMDb는 AWS WAF로 봇을 탐지하고 막아요. 가장 흔한 방아쇠는 User-Agent 헤더가 없거나 너무 대놓고 가짜인 경우예요. 이 문제는 여러 오픈소스 프로젝트와 IMDb 자체 커뮤니티 포럼에서 보고됐고, IMDb 직원도 인정한 바 있어요.
해결: 현실적인 브라우저 User-Agent 문자열과 Accept-Language: en-US 헤더를 늘 넣으세요. 연결 풀링엔 requests.Session()을 쓰고요.
결과가 25개만 나옴
IMDb 검색 페이지와 "Most Popular" 목록은 지연 로딩을 써요. 처음엔 약 25개만 그리고, 스크롤할 때 AJAX로 나머지를 불러와요.
해결: 다음 섹션에서 설명할 URL 파라미터 페이지네이션을 쓰거나, 한 번 응답으로 250개를 다 주는 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가 더 낫고요.
의사결정 프레임워크: 단기 vs 장기 해법
- 단기 해법: 모든 선택자에
try/except를 붙이고, HTTP 상태 코드를 검증하고, 오류를 중단 대신 기록하기 - 중기 해법: CSS 선택자에서 JSON-LD 추출로 갈아타기(위 방법 2)
- 장기 해법: 대규모 분석엔 IMDb 공식 대량 데이터셋을 쓰거나, 페이지 구조를 매번 새로 읽어 AI가 자동 적응하는 Thunderbit 같은 도구 쓰기 — 관리할 선택자가 없어요
25개 결과 제한을 넘어서: IMDb 페이지네이션과 대용량 스크래핑
제가 본 경쟁 튜토리얼은 하나같이 딱 한 페이지만 긁어요. 페이지네이션은 안 다뤄요. 그런데 목록 하나보다 더 많은 데이터가 필요하면 금방 벽에 부딪혀요.
페이지네이션이 필요 없는 페이지
좋은 소식. Top 250 페이지는 서버 렌더링 응답 한 번에 250개 영화를 다 불러와요. JSON-LD와 __NEXT_DATA__ 둘 다 전체 데이터셋을 담고 있어요. 페이지네이션이 필요 없어요.
IMDb 검색 페이지네이션은 어떻게 작동할까요?
IMDb 검색 페이지는 start= URL 파라미터를 쓰며 50씩 늘어나요.
https://www.imdb.com/search/title/?groups=top_1000&start=1
https://www.imdb.com/search/title/?groups=top_1000&start=51
https://www.imdb.com/search/title/?groups=top_1000&start=101
결과를 페이지 단위로 가져오는 파이썬 루프는 이래요.
import time
all_movies = []
for start in range(1, 1001, 50): # 상위 1000개를 페이지 단위로 순회
url = f"https://www.imdb.com/search/title/?groups=top_1000&start={start}"
response = requests.get(url, headers=headers)
if response.status_code != 200:
print(f"start={start}에서 실패: {response.status_code}")
break
soup = BeautifulSoup(response.text, "lxml")
# 원하는 방법으로 영화 추출
# ...
print(f"start={start}부터 시작하는 페이지를 스크래핑했습니다")
time.sleep(3) # 예의를 지키세요 — IMDb는 빠른 요청 약 50회 이후 차단할 수 있습니다
여기서 time.sleep(3)이 중요해요. 커뮤니티 보고에 따르면 IMDb는 빠른 요청 약 50회 뒤부터 IP를 막기 시작해요. 2~5초 사이 랜덤 지연을 넣는 게 좋은 습관이에요.
스크래핑을 통째로 건너뛰는 경우: IMDb 공식 대량 데이터셋
정말 대규모 데이터가 필요하다면 IMDb는 datasets.imdbws.com에서 매일 갱신되는 무료 TSV 파일 7개를 제공해요.
| 파일 | 내용 | 크기 |
|---|---|---|
| title.basics.tsv.gz | 제목, 유형, 장르, 상영 시간, 연도 | 약 800MB |
| title.ratings.tsv.gz | 평균 평점, 투표 수 | 약 25MB |
| title.crew.tsv.gz | 감독, 작가 | 약 300MB |
| title.principals.tsv.gz | 주요 출연/제작진 | 약 2GB |
| title.akas.tsv.gz | 지역별 대체 제목 | 약 1.5GB |
| title.episode.tsv.gz | TV 에피소드 정보 | 약 200MB |
| name.basics.tsv.gz | 인물: 이름, 출생 연도, 대표작 | 약 700MB |
Pandas로 불러오는 것도 간단해요.
ratings = pd.read_csv("title.ratings.tsv.gz", sep="\t", compression="gzip")
basics = pd.read_csv("title.basics.tsv.gz", sep="\t", compression="gzip", low_memory=False)
# tconst(IMDb 타이틀 ID) 기준으로 병합
merged = basics.merge(ratings, on="tconst")
top_movies = merged[merged["titleType"] == "movie"].nlargest(250, "averageRating")
이 데이터셋은 2,600만 개 이상의 타이틀을 다뤄요. 페이지네이션도, 선택자도, 403 오류도 없어요. 다만 라이선스가 개인 및 비상업적 사용만 허용하므로, 데이터를 재배포하거나 되팔 수는 없어요.
노코드로 빠르게: Thunderbit가 페이지네이션까지 처리
페이지네이션이 걸린 IMDb 데이터가 필요한데 직접 페이지네이션 로직은 짜기 싫은 분들을 위해, Thunderbit는 클릭형 페이지네이션과 무한 스크롤을 둘 다 기본 지원해요. 긁으라고만 말하면 나머지는 Thunderbit이 처리해요. 지연 로딩 콘텐츠를 스크롤하는 것까지 포함해서요.
페이지네이션 IMDb 데이터용 Thunderbit 체험하기
파이썬으로 IMDb 스크래핑하기: 완전한 작동 코드(복사해서 바로 실행)
지금 바로 돌릴 수 있는 독립형 스크립트 두 개예요.
스크립트 A: BeautifulSoup 방식(CSS 선택자)
import requests
from bs4 import BeautifulSoup
import pandas as pd
url = "https://www.imdb.com/chart/top/"
headers = {
"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",
"Accept-Language": "en-US,en;q=0.9"
}
response = requests.get(url, headers=headers)
if response.status_code != 200:
print(f"오류: {response.status_code}")
exit()
soup = BeautifulSoup(response.text, "lxml")
movie_items = soup.select("li.ipc-metadata-list-summary-item")
movies = []
for item in movie_items:
try:
title = item.select_one("h3.ipc-title__text")
year = item.select_one("span.cli-title-metadata-item")
rating = item.select_one("span.ipc-rating-star--rating")
movies.append({
"title": title.text.strip() if title else "N/A",
"year": year.text.strip() if year else "N/A",
"rating": rating.text.strip() if rating else "N/A",
})
except Exception as e:
print(f"오류 때문에 영화 건너뜀: {e}")
df = pd.DataFrame(movies)
df.to_csv("imdb_top250_bs4.csv", index=False)
print(f"{len(df)}편의 영화를 저장했습니다")
print(df.head())
스크립트 B: JSON-LD 방식(추천)
import requests
from bs4 import BeautifulSoup
import json
import pandas as pd
url = "https://www.imdb.com/chart/top/"
headers = {
"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",
"Accept-Language": "en-US,en;q=0.9"
}
response = requests.get(url, headers=headers)
if response.status_code != 200:
print(f"오류: {response.status_code}")
exit()
soup = BeautifulSoup(response.text, "lxml")
script_tag = soup.find("script", {"type": "application/ld+json"})
if not script_tag:
print("JSON-LD 데이터를 찾지 못했습니다")
exit()
data = json.loads(script_tag.string)
movies = []
for item in data.get("itemListElement", []):
movie = item.get("item", {})
rating_info = movie.get("aggregateRating", {})
directors = movie.get("director", [])
director_names = ", ".join(
d.get("name", "") for d in (directors if isinstance(directors, list) else [directors])
)
movies.append({
"rank": item.get("position"),
"title": movie.get("name"),
"url": movie.get("url"),
"rating": rating_info.get("ratingValue"),
"votes": rating_info.get("ratingCount"),
"year": movie.get("datePublished", "")[:4],
"genre": ", ".join(movie.get("genre", [])),
"director": director_names,
"description": movie.get("description"),
})
df = pd.DataFrame(movies)
df.to_csv("imdb_top250_jsonld.csv", index=False)
print(f"{len(df)}편의 영화를 저장했습니다")
print(df.head())
두 스크립트 모두 오류 처리가 들어 있고 깔끔한 CSV를 만들어요. 스크립트 B는 감독·설명·URL까지 더 풍부한 데이터를 주고, 레이아웃 변화에도 더 강해요.
코딩 없이 IMDb를 스크래핑하는 법(Thunderbit 사용)
다들 파이썬을 쓰고 싶거나 쓸 필요가 있는 건 아니에요. 이번 주 최고 평점 영화를 스프레드시트로 바로 받고 싶은 운영 분석가일 수도, 연도별 장르 추세를 비교하려는 콘텐츠 전략가일 수도 있죠. 그럴 땐 스크래퍼를 직접 짜는 건 과한 일예요.
Thunderbit로 같은 데이터를 얻는 방법은 이래요.
시작 전에:
- 난이도: 초급
- 소요 시간: 약 2분
- 준비물: Chrome 브라우저, Thunderbit Chrome 확장 프로그램 (무료 플랜 사용 가능)
STEP 1: 긁을 IMDb 페이지로 이동해요. Chrome에서 IMDb Top 250(또는 다른 IMDb 목록/검색 페이지)을 열어요.
STEP 2: Thunderbit 사이드바에서 "AI 필드 추천"을 클릭해요. AI가 페이지를 스캔해 열을 추천해 줘요. 보통 제목·연도·평점·장르 등이 나오고, 페이지에 따라 몇 가지가 더 붙어요. 추천 필드가 담긴 미리보기 표가 떠요.
STEP 3: 필요하면 필드를 손봐요. 안 쓸 열은 지우고, "+ 열 추가"를 눌러 평이한 영어로 원하는 내용을 설명해 커스텀 열을 만들 수 있어요(예: "감독 이름" 또는 "투표 수").
STEP 4: "스크래핑"을 클릭해요. Thunderbit가 데이터를 뽑아요. 무한 스크롤이나 페이지네이션이 있는 페이지도 스크롤까지 알아서 처리해요.
STEP 5: 내보내기. 내보내기 버튼을 누르고 Excel·Google Sheets·CSV·Airtable·Notion 중 골라요. 데이터가 몇 초 안에 목적지에 들어가요.
여기서 진짜 핵심은 편의성만이 아니에요. Thunderbit의 AI가 매번 페이지 구조를 새로 읽는다는 점예요. IMDb가 레이아웃을 바꿔도 AI가 적응하죠. 업데이트할 선택자도, 고칠 코드도 없어요. 마감 직전 새벽 2시에 깨진 스크래퍼 때문에 식은땀 흘려 본 사람이라면, 이 가치를 잘 알 거예요.
Thunderbit는 서브페이지 스크래핑도 지원해요. 영화 상세 페이지로 들어가 출연진·감독·상영 시간처럼 목록 페이지엔 안 보이는 필드까지 표에 풍부하게 채워 주죠. 실제 모습이 궁금하면 Thunderbit YouTube 채널을 확인하세요.
IMDb 스크래핑은 합법일까요? 알아야 할 것들
포럼에서 사용자들은 대놓고 이렇게 물어요. "이렇게 하는 게 합법인가요? IMDb는 자기 사이트 긁는 걸 싫어하잖아요." 좋은 질문이고, 경쟁 기사들은 이 부분을 안 다뤄요.
IMDb의 robots.txt: Top 250 차트(/chart/top/), 개별 타이틀 페이지(/title/ttXXXXXXX/), 이름 페이지(/name/nmXXXXXXX/)는 robots.txt에서 막혀 있지 않아요. 막힌 경로엔 /find, /_json/*, /search/name-text, /user/ur*/ratings, 그리고 여러 AJAX 엔드포인트가 들어가요. Crawl-delay 지시문은 따로 없어요.
IMDb의 이용 약관: 관련 조항은 이렇게 말해요. "귀하는 당사의 명시적인 서면 동의 없이 이 사이트에서 데이터 마이닝, 로봇, 화면 스크래핑 또는 유사한 데이터 수집 및 추출 도구를 사용할 수 없어요." 또 다른 조항은 스크래핑한 데이터의 재판매나 상업적 사용을 금지해요.
실무적으로 무슨 뜻이냐면: 2024년 최근 법원 판결들(Meta v. Bright Data, X Corp v. Bright Data)에서는, 약관에 동의한 적 없는 사용자에겐 이용약관이 구속력이 없을 수 있다고 봤어요. 공개 접근 가능한 데이터를 로그인 없이 긁는 경우, 약관의 집행 가능성은 여전히 다툼의 여지가 있어요. 다만 이 법적 영역은 계속 변하고 있어요.
안전한 대안: IMDb 공식 다운로드 데이터셋은 개인 및 비상업적 사용이 명시적으로 허용돼요. TMDb API는 무료 API 키로 비교적 자유롭게 쓸 수 있어요. 확실하게 안전한 길을 원하면 둘 다 좋은 선택예요.
실무 가이드: 긁더라도 요청 사이에 적절한 지연(time.sleep(3))을 두고, 헤더를 제대로 넣고, robots.txt에서 막힌 경로는 건드리지 마세요. 상업 프로젝트라면 법률 전문가와 상의하거나 공식 데이터셋/API를 쓰세요.
Thunderbit 블로그에서 웹 스크래핑의 법적 의미를 자세히 다뤘어요.
결론: 파이썬으로 IMDb를 긁는 가장 알맞은 방법 고르기
짧게 정리하면 이래요.
- BeautifulSoup + CSS 선택자: 기초 익히기엔 좋아요. 다만 6~12개월마다 깨질 걸 각오하세요. 오류 처리는 늘 넣고요.
- JSON-LD 추출: 꾸준히 굴릴 파이썬 프로젝트라면 제 추천예요. Schema.org 표준을 따르고, CSS 클래스보다 훨씬 덜 바뀌며, 자바스크립트 렌더링 없이도 깔끔한 구조화 데이터를 줘요.
__NEXT_DATA__JSON: 개별 타이틀 페이지에서 더 풍부한 데이터(상영 시간, 전체 출연진, 줄거리, 포스터 이미지 등)가 필요할 때 보조로 쓰세요.- IMDb 공식 데이터셋: 대규모 분석에 가장 좋아요. 2,600만 개 이상 타이틀, 일일 업데이트, 스크래핑 불필요. 개인/비상업적 사용만 가능해요.
- Thunderbit: 코딩 하기 싫거나 유지보수 없이 빠르게 데이터를 얻고 싶은 사람에게 최고예요. AI가 레이아웃 변화에 적응하고, 페이지네이션을 처리하고, Excel·Sheets·Airtable·Notion으로 내보내요.
이 가이드를 북마크해 두세요. IMDb 구조가 또 바뀌면 제가 업데이트할게요. 코드를 통째로 건너뛰고 싶다면 Thunderbit 무료 플랜을 써보세요. IMDb 페이지에서 깔끔한 스프레드시트까지 얼마나 빨리 가는지 직접 확인할 수 있을 거예요. 다른 사이트도 함께 다루고 있다면, 웹사이트 데이터를 Excel로 스크래핑하는 방법 가이드에서 더 넓은 워크플로를 볼 수 있어요.
IMDb와 그 밖의 사이트를 위한 AI 웹 스크래퍼 체험하기 Get Started Free
자주 묻는 질문
IMDb를 스크래핑하는 건 합법인가요?
IMDb 이용 약관은 동의 없는 스크래핑을 금지하지만, 2024년 최근 법원 판결 이후 공개 접근 가능한 데이터에 대한 약관의 집행 가능성은 법적으로 여전히 다툼 중이에요. 가장 안전한 선택은 IMDb 공식 무료 데이터셋(개인/비상업적 사용)이나 TMDb API(무료 키)예요. 긁는다면 robots.txt를 지키고, 요청 사이에 적절한 지연을 두고, 막힌 경로는 피하세요. 상업적 용도라면 법률 전문가와 상담하세요.
왜 제 IMDb 스크래퍼는 빈 결과만 나오나요?
대부분 원인은 낡은 CSS 선택자예요. td.titleColumn이나 td.ratingColumn 같은 클래스는 2023년 6월 이후 사라졌어요. 해결책은 JSON-LD 추출(<script type="application/ld+json"> 태그 파싱)로 갈아타거나, 현재의 ipc- 접두사 클래스에 맞게 선택자를 업데이트하는 거예요. 또 User-Agent 헤더를 제대로 넣고 있는지도 확인하세요. 헤더가 없으면 403이 나고, 이게 빈 결과처럼 보일 수 있어요.
IMDb에서 25개보다 많은 결과를 어떻게 긁나요?
Top 250 페이지는 250개 영화를 한 번에 불러오니 페이지네이션이 필요 없어요. 검색 결과는 start= URL 파라미터를 50씩 늘리며 페이지를 넘기세요. 예를 들면 start=1, start=51, start=101예요. 차단을 피하려면 요청 사이에 time.sleep(3)을 넣고요. 또는 datasets.imdbws.com의 IMDb 공식 데이터셋은 2,600만 개 이상 타이틀을 담고 있어 페이지네이션이 아예 필요 없어요.
__NEXT_DATA__는 뭐고, 왜 IMDb 스크래핑에 써야 하나요?
__NEXT_DATA__는 IMDb의 React/Next.js 페이지 안 <script id="__NEXT_DATA__"> 태그에 담긴 JSON 객체예요. 페이지를 그릴 때 React가 쓰는 전체 구조화 데이터를 담고 있죠. 제목·평점·출연진·장르·상영 시간 등 화면 레이아웃이 아니라 실제 데이터 모델을 나타내므로, CSS 선택자보다 UI 재설계에 훨씬 강해요. 가장 견고한 추출을 원하면 JSON-LD와 함께 쓰세요.
코딩 없이 IMDb를 스크래핑할 수 있나요?
네. 대표적인 길이 두 가지예요. (1) IMDb 공식 대량 데이터셋 내려받기 — 2,600만 개 이상 타이틀을 담은 TSV 파일 7개, 일일 업데이트, 비상업적 사용 무료. (2) Thunderbit의 AI 웹 스크래퍼 사용 — IMDb 페이지를 읽고 추출 필드를 자동 추천한 뒤, 클릭 두 번으로 Excel·Google Sheets·CSV로 내보내요. 코드도 없고, 관리할 선택자도 없어요.
더 알아보기


