
本文详解如何通过 requests + beautifulsoup 正确提取 imdb 排行榜页面中每部剧集的详情页链接,重点解决 403 错误、无效爬取及链接泛化问题,并提供可直接运行的健壮代码示例。
本文详解如何通过 requests + beautifulsoup 正确提取 imdb 排行榜页面中每部剧集的详情页链接,重点解决 403 错误、无效爬取及链接泛化问题,并提供可直接运行的健壮代码示例。
在使用 Python 进行网页数据采集时,尤其是针对 IMDb 这类反爬机制较严格的网站,常见失败原因并非代码逻辑错误,而是忽略了 HTTP 请求的基本规范。你提供的两段代码均未设置请求头(headers),导致服务器返回 403 Forbidden 响应(虽可能静默处理为首页内容),从而无法获取真实目标链接——这也是为何只得到主站 URL 或空/杂乱结果的根本原因。
此外,原始代码中采用递归遍历全站所有 <a> 标签的方式存在严重缺陷:
- ❌ 无目标过滤:抓取了导航栏、广告、页脚等无关链接;
- ❌ 无限递归风险:未限制深度或域名范围,易陷入死循环或触发风控;
- ❌ 协议混淆:IMDb 的剧集链接多为相对路径(如 /title/tt1234567/),直接拼接 https:// 会导致 404;
- ❌ 缺乏容错与去重:未处理空 href、重复链接或异常字符。
✅ 正确做法是:精准定位 + 合规请求 + 结构化提取。以下为优化后的完整方案:
import requests
from bs4 import BeautifulSoup
import pandas as pd
# 关键:设置合法 User-Agent,模拟真实浏览器请求
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"
}
url = "https://www.imdb.com/chart/toptv/"
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # 显式抛出网络错误
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
exit()
soup = BeautifulSoup(response.content, "html.parser")
# 使用 CSS 选择器精准定位:href 以 "/title/" 开头 且 包含 <h3> 标签的 <a> 元素
# 此 selector 直接对应 IMDb 榜单中每一行剧集标题的锚点
show_links = soup.select('a[href^="/title/"]:has(h3)')
# 提取结构化数据:完整 URL + 清洗后的剧名
data = []
for a in show_links:
href = a.get("href")
if href and href.startswith("/title/"):
full_url = f"https://www.imdb.com{href.rstrip('/')}/" # 标准化结尾斜杠
# 提取标题:通常格式为 "1. Stranger Things" → 取 ". " 后部分
raw_text = a.get_text(strip=True)
title = raw_text.split(". ", 1)[-1] if ". " in raw_text else raw_text
data.append({"url": full_url, "title": title})
# 生成 DataFrame 并保存
df = pd.DataFrame(data)
print(f"成功提取 {len(df)} 部剧集链接")
print(df.head())
# 可选:导出 CSV
# df.to_csv("imdb_top_tv_shows.csv", index=False, encoding="utf-8-sig")? 关键要点总结:
立即学习“Python免费学习笔记(深入)”;
- 必须设置 User-Agent:否则多数现代网站会拒绝请求;
- 用 soup.select() 替代 find_all():CSS 选择器语法更简洁、语义更明确,[href^="/title/"] 表示“href 属性以 /title/ 开头”,:has(h3) 确保该链接内嵌剧名标题(避免抓取海报图、评分图标等干扰元素);
- 手动拼接绝对 URL:IMDb 所有剧集页均为相对路径,需补上前缀 https://www.imdb.com;
- 添加异常处理与超时:提升脚本鲁棒性;
- 避免递归爬取:本场景只需单页解析,无需深度遍历。
⚠️ 注意事项:
- IMDb 明确禁止未经许可的大规模自动化抓取,请遵守 robots.txt(https://www.imdb.com/robots.txt)并控制请求频率(建议 ≥ 2 秒间隔);
- 若需长期项目,建议注册 IMDb API 或使用官方数据集;
- 本代码适用于教学与小规模分析,生产环境请增加代理轮换、会话管理及 HTML 结构变更监控。
掌握这种“精准选择器 + 合规请求”的范式,可高效复用于豆瓣、烂番茄等主流影视平台的数据采集任务。


















