使用 Python 抓取 IMDb:真正可運作的程式碼

最後更新於 April 28, 2026
使用 Python 抓取 IMDb:真正可運作的程式碼

如果您最近搜尋過「使用 Python 抓取 IMDb」,大概已經發現一件事:大多數找到的教學都壞了。不是那種「稍微過時」的壞,而是更像「回傳零結果,還冒出一整片 NoneType 錯誤」的壞。

過去幾週,我測試了我能找到的所有主流 IMDb 抓取教學——GeeksforGeeks、Medium、freeCodeCamp、Kaggle notebooks,想到的我都試了。在 214+ 個公開 GitHub repository 中,絕大多數都還在引用 td.titleColumntd.ratingColumn 這些 CSS selector,但它們自從 2023 年 6 月 IMDb 重新設計 Top 250 頁面後就不存在了。結果呢?論壇裡滿是開發者在問「為什麼我的程式回傳空值?」;而像 Cinemagoer 這類熱門函式庫的維護者也坦承:「除了把每個 parser 都修一遍,我們也沒太多辦法。」本指南會介紹兩種目前真正可用的 Python 方法、如何處理分頁和常見錯誤、什麼時候 Python 其實不是最佳工具,以及如何讓你的爬蟲更耐用,避免很快就進入廢墟名單。

用 Python 抓取 IMDb 是什麼意思?

網頁爬蟲是指以程式方式從網頁擷取資料——不必手動複製貼上,而是寫一段程式替您完成。當我們說「抓取 IMDb」時,指的是用 Python 從 IMDb 的網頁中擷取結構化電影資料(片名、評分、類型、演員、片長、投票數等)。

Python 常見的工具組合通常有三個函式庫:requests(用來取得網頁)、BeautifulSoup(解析 HTML 並找出資料)、pandas(整理與匯出結果)。有些教學也會用 SeleniumPlaywright 來處理需要 JavaScript 渲染的頁面,但您會看到,其實還有更快的方法。

有一個重要提醒:本指南中的所有內容都已依照 IMDb 目前的頁面結構驗證,截至 2025 年中仍可使用。IMDb 大約每 6–12 個月就會變動一次,因此如果您是在 2027 年閱讀這篇文章,部分 selector 可能已經改了。(我也會說明怎麼處理這種情況。)

為什麼要用 Python 抓取 IMDb?實際應用場景有哪些?

在寫任何一行程式之前,先想想:您實際會拿 IMDb 資料做什麼?答案取決於您的角色。

IMDb 評論資料集是全球最常用的 NLP 基準資料集之一——Maas 等人 2011 年的基礎論文已累積 5,706 次引用,而且這份資料集已內建於 TensorFlow、Keras 和 PyTorch。Hugging Face 上的 stanfordnlp/imdb 資料集每月下載量達 213,321 次,並被用來訓練超過 1,500 個模型。所以如果您在做機器學習,應該對 IMDb 資料不陌生。

但它的用途遠不只學術研究:

用途適合對象需要的資料欄位
電影推薦引擎資料科學家、愛好者片名、類型、評分、演員
串流平台內容策略產品/內容團隊評分、投票數、上映年份、類型
情感分析/NLP 訓練ML 研究人員、學生評論、評分
競品內容分析娛樂產業分析師票房、上映日期、評分趨勢
影視觀光研究觀光局、旅遊公司拍攝地點、熱度指標
學術研究大學研究人員任何結構化電影中繼資料

光是影視觀光市場在 2025 年全球估值就達 $660 億美元。Netflix 在 2024 年就投入超過 170 億美元製作內容,且 80% 的觀看行為 都是由個人化推薦驅動。重點是:IMDb 資料正在支持各產業的真實決策。

取得 IMDb 資料的選項:在寫程式前先看這裡

這一段通常是大多數教學完全跳過的。他們直接叫您 pip install beautifulsoup4,卻沒有先問:在您的情境下,Python 抓取真的最適合嗎?

完整選項如下:

方式最適合優點缺點
Python + BeautifulSoup學習、客製化擷取完全掌控、彈性高selector 脆弱、常常壞掉
JSON-LD / __NEXT_DATA__ 擷取想要穩定性的開發者可處理 JS 內容、韌性更高需要理解 JSON 結構
IMDb 官方資料集大規模分析、學術用途合法、完整、2600 萬+ 標題、每日更新TSV 格式、沒有評論/圖片
Cinemagoer(IMDbPY)函式庫逐筆查詢單一標題Python 風格 API、欄位豐富88 個未解問題,最後一次發版是 2023 年 5 月
TMDb API電影中繼資料 + 圖片免費 API 金鑰、JSON、文件完整來源不同(不是 IMDb 評分)
Thunderbit(無程式碼)不寫程式的人、快速匯出2 步驟抓取、AI 自動建議欄位、可匯出到 Excel/Sheets大量抓取需使用點數制

這些選項有幾點要注意。Cinemagoer 自 2023 年 5 月後就沒有 PyPI 發版,而且 IMDb 在 2025 年 6 月重新設計頁面後,它的大多數 parser 都壞了——我目前不建議拿它直接上線生產環境。TMDb 很不錯,但它使用的是自己的評分系統,不是 IMDb 的。至於 IMDb 的官方企業 API,透過 AWS Data Exchange 每年要價 $50,000 以上,所以對我們大多數人來說並不實際。

如果您完全不想寫程式,Thunderbit 的人工智慧網頁爬蟲 可以直接讀取 IMDb 頁面,自動建議擷取欄位(片名、評分、年份、類型),並在兩次點擊內匯出到 Excel、Google Sheets、Airtable 或 Notion。當 IMDb 改版時,AI 也會自動適應,所以不需要維護任何 selector。後面我會再詳細說明。

現在,對於真的想寫 Python 的人——下面是兩種可用的方法。

方法 1:使用 BeautifulSoup 用 Python 抓取 IMDb(傳統作法)

這是大多數教學裡最常見的經典做法。它能用,但我先講清楚:在我介紹的方法裡,這是最脆弱的一種。IMDb 的 CSS class 名稱是自動產生的,頁面改版時就會變。話雖如此,它仍然是學習網頁爬蟲基礎最好的方式。

步驟 1:安裝並匯入 Python 函式庫

您需要四個套件:

pip install requests beautifulsoup4 pandas lxml

各自的用途如下:

  • requests — 發送 HTTP 請求,取得網頁內容
  • beautifulsoup4 — 解析 HTML,方便您搜尋特定元素
  • pandas — 將擷取到的資料整理成表格,並匯出為 CSV/Excel
  • lxml — 速度很快的 HTML parser(BeautifulSoup 可以把它當作後端)

匯入程式碼:

import requests
from bs4 import BeautifulSoup
import pandas as pd

步驟 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 地理位置回傳不同語言的內容。

步驟 3:用 BeautifulSoup 解析 HTML

有了 HTML 之後,建立一個 BeautifulSoup 物件,開始找對應的元素。打開 Chrome 裡的 IMDb Top 250 頁面,對著某個電影標題按右鍵,再點「檢查」,就能看到底層 HTML 結構。

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

截至 2025 年中,Top 250 頁面使用以下 selector:

  • 電影容器li.ipc-metadata-list-summary-item
  • 標題h3.ipc-title__text
  • 年份span.cli-title-metadata-item(第一個 span)
  • 評分span.ipc-rating-star--rating

提醒一下:那些以 ipc- 開頭的 class 名稱是 IMDb 元件系統自動產生的。它們自 2023 年 6 月改版後一直很穩定,但不保證未來不會再變。

步驟 4:擷取電影資料(標題、年份、評分)

這裡我和多數教學不一樣:我加入了 try/except 錯誤處理。我看過的競品教學幾乎都沒有這個步驟,這也是為什麼 selector 一改,他們的程式就默默壞掉。

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)} 部電影")

步驟 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. The Shawshank Redemption  1994    9.3
1           2. The Godfather    1972    9.2
2     3. The Dark Knight        2008    9.0
3  4. The Godfather Part II     1974    9.0
4         5. 12 Angry Men       1957    9.0

這樣確實可行。但它是靠那些可能隨時失效的 CSS selector 撐著——這也正是我真正推薦的下一種方法。

方法 2:JSON-LD 技巧——完全跳過 HTML 解析

這是沒有競品文章提到的方法,也是我在任何正式專案中會採用的方式。IMDb 會在每個頁面的 <script type="application/ld+json"> 標籤中嵌入結構化資料,也就是 JSON-LD(Linked Data 的 JavaScript Object Notation)。這些資料遵循 Schema.org 標準,Google 也用它來產生豐富搜尋結果,而且變動頻率遠低於 CSS class 名稱。

Apify 的 IMDb Scraper 是一個可上線使用的工具,它採用的擷取優先順序是:「JSON-LD > NEXT_DATA > DOM」。我也會建議您用這個順序。

為什麼 JSON-LD 比 CSS selector 更可靠

方法可處理 JS 內容?對 UI 變動的韌性?速度複雜度
BeautifulSoup + CSS selector❌ 否⚠️ 脆弱(class 名稱會變)
JSON-LD 擷取✅ 是✅ 遵循 Schema.org 標準低-中
__NEXT_DATA__ JSON 擷取✅ 是✅ 相當穩定低-中
Selenium / Playwright✅ 是⚠️ 脆弱中-高
Thunderbit(無程式碼,2 步驟)✅ 是(AI 讀取頁面)✅ AI 會自動適應

ipc-metadata-list-summary-item 這類 CSS class 名稱,是 IMDb React 元件系統自動產生的,每次改版都可能變。JSON-LD schema 表示的是實際資料模型,而不是呈現層。就像您是看一本書的目錄,還是只靠字體大小去猜哪一章是什麼,差別非常大。

css-selectors-vs-json-ld.webp

逐步操作:從 JSON-LD 擷取 IMDb 資料

步驟 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")

步驟 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"找到的 JSON-LD 類型:{data.get('@type', 'unknown')}")

步驟 3:解析結構化資料

在 Top 250 頁面中,JSON-LD 會包含一個 itemListElement 陣列,裡面有全部 250 部電影。每個項目都包含位置、名稱、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"),
    })

步驟 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  The Shawshank Redemption  https://www.imdb.com/title/tt0111161/     9.3     2900000     1994-10-14     Drama
1     2            The Godfather   https://www.imdb.com/title/tt0068646/     9.2     2000000     1972-03-24     Crime, Drama
2     3          The Dark Knight   https://www.imdb.com/title/tt0468569/     9.0     2800000     2008-07-18     Action, Crime, Drama

全部 250 部電影。乾淨、結構化,完全不需要和 CSS selector 糾纏。更重要的是,這份資料遵循 Schema.org 標準(Google 也依賴它來產生搜尋結果),所以比視覺版面穩定得多。

加碼:單一電影頁面的 __NEXT_DATA__

如果您想從單一標題頁取得更豐富的資料(片長、完整演員表、劇情摘要、海報圖片),IMDb 也會嵌入 __NEXT_DATA__ JSON 物件。這是 React 用來 hydrate 頁面的資料——如果移除它,網站就會壞掉。

# 在單一電影頁,例如 /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 月姓名頁面改版舊的姓名頁抓取器
2023 年 6 月Top 250 頁面改版所有 td.titleColumn / td.ratingColumn selector
2023 年 4 月標題子頁改版Biography、awards、news 抓取器
2023 年 10 月進階搜尋改版以搜尋頁為基礎的抓取器
2025 年 6 月/reference 頁面改版Cinemagoer 函式庫(大多數 parser)

大約每 6–12 個月就會有一次重大破壞性變更。如果您的爬蟲依賴 CSS class 名稱,那您基本上就是在跑步機上追著問題跑。

常見錯誤與修正方式

空結果/NoneType 錯誤

這是最常見的錯誤。您會看到 AttributeError: 'NoneType' object has no attribute 'text'。這代表 BeautifulSoup 沒找到您要的元素——通常是 CSS class 名稱變了,或內容是由 JavaScript 渲染。

修正方式:改用 JSON-LD 擷取(上面的方法 2)。資料本來就在初始 HTML 回應裡,不需要 JavaScript。

403 Forbidden

IMDb 使用 AWS WAF 來偵測並封鎖機器人。最常見的觸發原因,是缺少或明顯假的 User-Agent 標頭。這點在 多個 開源專案與 IMDb 官方社群論壇 都有記錄,連 IMDb 員工也曾承認這個問題。

修正方式:一定要帶上看起來像真實瀏覽器的 User-Agent 字串,以及 Accept-Language: en-US 標頭。連線池則建議使用 requests.Session()

只回傳 25 筆結果

IMDb 的搜尋頁和「Most Popular」列表會使用 lazy loading——一開始只渲染約 25 筆結果,接著隨著您捲動,再透過 AJAX 載入更多。

修正方式:使用 URL 參數分頁(下一節會講),或改抓 Top 250 頁面,因為它會在單次回應中載入全部 250 部電影。

selector 突然失效

以下是已經失效的舊 selector:td.titleColumntd.ratingColumn.lister-item-header.inline-block.ratings-imdb-rating。如果您的程式用了這些,現在就是壞的。

修正方式:優先使用 data-testid 屬性(例如 h1[data-testid="hero-title-block__title"]),不要再靠自動產生的 class 名稱。更好的做法是直接用 JSON-LD。

決策框架:短期修法 vs 長期修法

  • 快速修法:在每個 selector 外面加上 try/except、驗證 HTTP 狀態碼、記錄錯誤而不是直接崩潰
  • 中期修法:從 CSS selector 改成 JSON-LD 擷取(方法 2)
  • 長期修法:大規模分析時,使用 IMDb 官方批次資料集,或像 Thunderbit 這樣每次都用 AI 重新讀取頁面結構的工具——不需要維護 selector,AI 會自動適應版面變動

超越 25 筆限制:IMDb 分頁與大型資料集抓取

我看過的每一篇競品教學都只抓單一頁面。沒有人講分頁。但如果您需要的不只是一個清單,很快就會撞牆。

不需要分頁的頁面

好消息是:Top 250 頁面會在單次 server-rendered 回應中載入全部 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

下面是一個用 Python 逐頁抓取結果的迴圈:

import time

all_movies = []

for start in range(1, 1001, 50):  # 逐頁抓取 top 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} 開始的頁面")
    time.sleep(3)  # 請保持節制——IMDb 大約在 50 次快速請求後會開始封鎖

time.sleep(3) 很重要。社群回報顯示,IMDb 大約在 50 次快速請求後就會開始封鎖 IP。建議使用 2–5 秒之間的隨機延遲。

什麼時候應該完全不抓取:IMDb 官方批次資料集

如果您真的需要大規模資料,IMDb 提供 7 個免費 TSV 檔案,可在 datasets.imdbws.com 下載,且每天更新:

檔案內容大小
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 很簡單:

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 title ID)合併
merged = basics.merge(ratings, on="tconst")
top_movies = merged[merged["titleType"] == "movie"].nlargest(250, "averageRating")

這些資料集涵蓋 2,600 萬以上的標題。不用分頁、不用 selector,也沒有 403 錯誤。授權僅限個人與非商業用途——不能重新發布或轉售這些資料。

無程式碼捷徑:Thunderbit 幫您處理分頁

如果您需要有分頁的 IMDb 資料,但又不想自己寫分頁邏輯,Thunderbit 原生支援點擊式分頁與無限捲動。您只要告訴它要抓什麼,其他都交給它——包含處理 lazy-loaded 內容。

試試 Thunderbit 來抓取分頁式 IMDb 資料

用 Python 抓取 IMDb:完整可用程式碼(可直接複製貼上)

下面有兩個可直接執行的完整腳本。

腳本 A:BeautifulSoup 方法(CSS selector)

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

不是每個人都需要或想要寫 Python。也許您是營運分析師,只想把這週評分最高的電影整理成試算表;也許您是內容策略師,想比較不同年份的類型趨勢。在這些情況下,自己寫爬蟲反而太重了。

以下是用 Thunderbit 取得相同資料的方法:

開始前先準備:

步驟 1:前往您要抓取的 IMDb 頁面。 在 Chrome 中打開 IMDb Top 250(或任何其他 IMDb 清單/搜尋頁)。

步驟 2:在 Thunderbit 側邊欄點擊「AI Suggest Fields」。 AI 會掃描頁面並推薦欄位——通常會是標題、年份、評分、類型,以及其他幾個欄位,視頁面而定。您會看到一個預覽表格,裡面列出建議的欄位。

步驟 3:需要的話調整欄位。 移除不需要的欄位,或點擊「+ Add Column」並用白話英文描述您想要的內容(例如「Director name」或「Number of votes」)。

步驟 4:點擊「Scrape」。 Thunderbit 就會擷取資料。若頁面有無限捲動或分頁,它也會自動處理。

步驟 5:匯出。 點擊匯出按鈕並選擇格式——Excel、Google Sheets、CSV、Airtable 或 Notion。資料會在幾秒內送到您的目的地。

這裡真正的優勢不只是方便——而是 Thunderbit 的 AI 每次都會重新讀取頁面結構。當 IMDb 改版時(而且它一定會改),AI 也會跟著適應。不需要更新 selector,也不需要修程式。對任何曾在截止日前的凌晨兩點被壞掉的爬蟲折磨過的人來說,這非常值得。

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 endpoint。它也沒有指定 Crawl-delay

IMDb 的使用條款:相關條款寫道:「除非獲得我們明確的書面同意,否則你不得在本網站上使用資料探勘、機器人、畫面抓取或類似的資料收集與擷取工具。」 另一條則禁止轉售或商業使用抓取資料。

實務上代表什麼:近期 2024 年的法院判決(Meta v. Bright Data、X Corp v. Bright Data)認為,若使用者從未同意服務條款,那麼條款未必一定能約束使用公開資料的人——如果您是在未登入狀態下抓取公開可見內容,條款的可執行性其實有爭議。但這仍然是一個持續演變中的法律領域。

較安全的替代方案:IMDb 的 官方可下載資料集 明確允許個人與非商業用途。TMDb API 只要免費 API key 也相當寬鬆。如果您想明確站在安全一側,這兩者都是很好的選項。

實務建議:如果您真的要抓,請使用尊重對方伺服器的抓取頻率(每次請求間隔 time.sleep(3))、設定正確的標頭,並避免碰觸被 robots.txt 封鎖的路徑。若是商業專案,請諮詢法律專業人士,或直接使用官方資料集/API。

我們也在 Thunderbit 部落格上深入討論過 網頁爬蟲的法律影響

結論:選擇最適合的 IMDb Python 抓取方式

簡短總結:

  • BeautifulSoup + CSS selector:適合學習基礎。預期它每 6–12 個月就會壞一次。一定要加上錯誤處理。
  • JSON-LD 擷取:如果您要長期維護 Python 專案,我最推薦這個方法。它遵循 Schema.org 標準,比 CSS class 變動少得多,而且不需要 JavaScript 渲染就能拿到乾淨的結構化資料。
  • __NEXT_DATA__ JSON:可作為補充,用來取得單一標題頁更豐富的資料(片長、完整演員表、劇情、海報圖片)。
  • IMDb 官方資料集:大規模分析的最佳選擇。2600 萬+ 標題、每日更新、無需抓取。僅限個人/非商業用途。
  • Thunderbit:最適合不寫程式的人,或任何想快速拿到資料、又不想維護程式的人。AI 會適應版面變動、處理分頁,並可匯出到 Excel/Sheets/Airtable/Notion。

把這篇指南存起來——下次 IMDb 結構再變時,我會更新它。如果您想完全跳過程式,試試 Thunderbit 的免費方案,看看您能多快從 IMDb 頁面得到乾淨的試算表。如果您也在處理其他網站,我們關於 將網站資料抓取到 Excel 的指南會涵蓋更完整的流程。

試用適用於 IMDb 與更多網站的 AI 網頁爬蟲 Get Started Free

常見問題

抓取 IMDb 合法嗎?

IMDb 的使用條款禁止在未經同意的情況下抓取,但在近期 2024 年法院判決後,針對公開可存取資料的條款可執行性在法律上仍有爭議。最安全的選擇是 IMDb 的 官方免費資料集(限個人/非商業用途)或 TMDb API(免費 key)。如果您確實要抓,請尊重 robots.txt、在請求之間保留合理延遲,並避免被封鎖的路徑。商業用途請諮詢法律專業人士。

為什麼我的 IMDb 爬蟲回傳空結果?

幾乎總是因為過時的 CSS selector——像 td.titleColumntd.ratingColumn 這些 class 自 2023 年 6 月後就不存在了。解法是改用 JSON-LD 擷取(解析 <script type="application/ld+json"> 標籤),或將 selector 更新為目前以 ipc- 開頭的 class。同時也要確認您有加上正確的 User-Agent 標頭,因為缺少該標頭時會觸發 403 錯誤,看起來就像空結果。

我要怎麼抓超過 25 筆 IMDb 結果?

Top 250 頁面會在單次回應中載入全部 250 部電影——不需要分頁。搜尋結果則可以使用 start= URL 參數(每次增加 50)逐頁抓取。例如:start=1start=51start=101。請在每次請求之間加入 time.sleep(3),避免被封鎖。或者,您也可以直接使用 IMDb 官方資料集 datasets.imdbws.com,其中包含 2600 萬+ 標題,不需要分頁。

什麼是 __NEXT_DATA__,為什麼要用它抓 IMDb?

__NEXT_DATA__ 是 IMDb React/Next.js 頁面中嵌在 <script id="__NEXT_DATA__"> 標籤裡的一個 JSON 物件。它包含 React 用來渲染頁面的完整結構化資料——標題、評分、演員、類型、片長等等。因為它代表的是底層資料模型,而不是視覺版面,所以比 CSS selector 更能抵抗 UI 改版。將它和 JSON-LD 搭配使用,是最穩健的擷取方式。

可以不寫程式就抓 IMDb 嗎?

可以。主要有兩種方式:(1) 下載 IMDb 的 官方批次資料集——7 個 TSV 檔,涵蓋 2600 萬+ 標題,每日更新,供非商業用途免費使用。(2) 使用 Thunderbit 的人工智慧網頁爬蟲,它會讀取 IMDb 頁面、自動建議擷取欄位,並在兩次點擊內匯出到 Excel、Google Sheets 或 CSV——不用寫程式,也不用維護 selector。

延伸閱讀

Ke
Ke
Thunderbit 技術長|資深資料科學家與機器學習專家 Ke Shen 在機器學習與資料科學領域擁有近十年經驗,畢業於哥倫比亞大學,曾任 Walmart Labs 資深資料科學家。他精通 Python、R、Java 與統計學,且具備深受同儕認可的深厚專業,分享如何將複雜的 AI 演算法從理論落實到可投入生產的架構的實戰見解。
目錄

只要提問,就能抓取網頁

用白話告訴它你要什麼,或者更好,什麼都不用說。

立即體驗 Thunderbit free
使用 AI 擷取資料
輕鬆將資料轉移到 Google Sheets、Airtable 或 Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week