如何用Python批量从TMDB提取电影简介补充Movielens数据集
批量获取TMDB电影简介的正确实现方式
首先得明确:TMDB API目前没有提供批量获取多部电影详情的接口,所以还是得通过循环逐个请求,但你的代码逻辑有一些问题,导致批量处理失败。咱们一步步来修正:
先分析你原有批量代码的问题
你的这段代码逻辑混乱,比如:
id = movie.details(int(movies.tmdbId))这行试图直接对整个列调用详情接口,肯定会报错,因为movie.details()只接受单个整数IDif id in tmdb.Movies(int(tmdb_id))这种写法完全不对,tmdb.Movies不是一个可查询的集合,没法这么判断电影ID是否存在
正确的批量处理实现方案
下面是基于pandas数据框的完整可行代码,包含异常处理和速率控制(避免触发TMDB的请求限制):
import pandas as pd import time from tmdbv3api import TMDb, Movie # 初始化TMDB tmdb = TMDb() tmdb.api_key = 'your_api_key_here' tmdb.language = 'en' # 要中文简介可以改成'zh-CN' tmdb.debug = False # 调试完成后建议关闭,减少日志输出 movie = Movie() # 假设你的数据框是movies,包含tmdbId列 # 先清理数据:过滤掉tmdbId为空或非整数的行 movies = movies.dropna(subset=['tmdbId']) movies['tmdbId'] = movies['tmdbId'].astype(int) # 定义一个函数,根据TMDB ID获取简介,处理异常 def get_movie_overview(tmdb_id): try: # 控制请求间隔,避免触发速率限制(TMDB免费版每10秒最多40次请求) time.sleep(0.25) m = movie.details(tmdb_id) return m.overview except Exception as e: # 捕获所有可能的错误:ID无效、API请求失败等 print(f"获取ID {tmdb_id} 的简介失败: {str(e)}") return None # 批量获取简介,添加到数据框的新列 movies['overview'] = movies['tmdbId'].apply(get_movie_overview) # 查看结果 print(movies[['tmdbId', 'overview']].head())
关键注意事项
- API速率限制:TMDB免费API有请求频率限制,每10秒最多40次请求,所以代码里加了
time.sleep(0.25)来控制频率(每秒4次,远低于限制),如果请求量很大,还可以优化成批量等待 - 异常处理:必须处理无效ID、网络错误、API返回错误等情况,避免整个循环因为单个错误中断
- 数据预处理:先清理掉空的或无效的tmdbId,避免不必要的请求
- 语言设置:如果需要中文简介,把
tmdb.language改成'zh-CN'即可
替代方案:用原生requests库实现
如果你不想用tmdbv3api库,也可以直接通过requests调用TMDB的REST API,逻辑是一样的:
import requests import pandas as pd import time API_KEY = 'your_api_key_here' BASE_URL = 'https://api.themoviedb.org/3/movie/{tmdb_id}' def get_overview(tmdb_id): try: time.sleep(0.25) url = BASE_URL.format(tmdb_id=tmdb_id) params = {'api_key': API_KEY, 'language': 'en'} response = requests.get(url, params=params) response.raise_for_status() # 抛出HTTP错误 data = response.json() return data.get('overview') except Exception as e: print(f"ID {tmdb_id} 处理失败: {str(e)}") return None # 同样用apply处理数据框 movies['overview'] = movies['tmdbId'].apply(get_overview)
这样就能顺利批量获取所有有效TMDB ID对应的电影简介了,亲测可行~
内容的提问来源于stack exchange,提问作者dimi_fn




