如何通过IMDB的pagination-container加载某剧集的全部集数数据?
如何通过IMDB的pagination-container加载某剧集的全部集数数据?
嘿,我之前爬IMDB剧集数据的时候也碰到过一模一样的问题!IMDB的剧集页面默认只会渲染部分内容,剩下的是通过点击“30 more”按钮触发AJAX动态加载的,所以你用requests.get拿初始页面源码,自然只能拿到已经渲染好的50集。
给你两种实用的解决方案,选哪种看你的需求:
方案一:用Selenium模拟点击加载更多(简单直观)
这种方法就像你手动打开浏览器点击按钮一样,适合不想折腾API接口的情况:
首先得先安装Selenium,同时下载对应浏览器的驱动(比如ChromeDriver,要和你的浏览器版本匹配):
pip install selenium
然后是具体代码:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from bs4 import BeautifulSoup import time url = 'https://www.imdb.com/title/tt5189554/episodes/' # 初始化Chrome驱动,若已将驱动加入系统PATH,可省略executable_path参数 driver = webdriver.Chrome(executable_path='./chromedriver') driver.get(url) try: # 等待"30 more"按钮加载完成,最多等待10秒 more_button = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "button.ipc-see-more__button")) ) # 点击按钮加载剩余剧集 more_button.click() # 等待页面加载完成,也可以用显式等待监听新内容出现 time.sleep(3) # 获取加载完成后的完整页面源码 full_page_source = driver.page_source soup = BeautifulSoup(full_page_source, 'html.parser') # 提取剧集数据(class名需根据当前IMDB页面结构调整,以下为常见容器类) episode_containers = soup.find_all('div', class_='sc-f09bd1f5-0') for container in episode_containers: # 从a标签href中提取剧集ID(格式为/title/ttxxxxxx/) episode_id = container.find('a')['href'].split('/')[2] # 提取剧集名称 episode_name = container.find('h3').get_text(strip=True) print(f"剧集ID: {episode_id}, 剧集名称: {episode_name}") finally: # 无论成功与否,最后都关闭浏览器 driver.quit()
方案二:直接调用IMDB的AJAX接口(高效推荐)
如果你不想用Selenium模拟浏览器,直接抓取IMDB加载更多的接口会更轻量。操作思路是:
- 打开浏览器F12开发者工具,切换到Network标签
- 点击页面上的“30 more”按钮,观察Network中的XHR请求,找到加载更多的接口
- 这个接口需要的参数(比如
paginationKey)其实在初始页面的HTML里就能拿到
具体代码如下:
import requests from bs4 import BeautifulSoup url = 'https://www.imdb.com/title/tt5189554/episodes/' headers = { "Connection": "keep-alive", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" } # 先获取初始页面,拿到已加载的50集和分页key response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') # 从你提到的pagination-container中提取分页需要的paginationKey pagination_container = soup.find('div', class_='sc-f09bd1f5-1 hoKmdt pagination-container') pagination_key = pagination_container.get('data-pagination-key') # 构造加载更多的AJAX请求URL,参数需与你观察到的接口一致 ajax_url = f"https://www.imdb.com/title/tt5189554/episodes/_ajax?season=1&ref_=tt_eps_sn_1&paginationKey={pagination_key}" # 发送AJAX请求拿到剩余剧集 ajax_response = requests.get(ajax_url, headers=headers) ajax_soup = BeautifulSoup(ajax_response.text, 'html.parser') # 合并初始页面和AJAX返回的所有剧集容器 all_episode_containers = soup.find_all('div', class_='sc-f09bd1f5-0') + ajax_soup.find_all('div', class_='sc-f09bd1f5-0') # 遍历提取数据 for container in all_episode_containers: episode_id = container.find('a')['href'].split('/')[2] episode_name = container.find('h3').get_text(strip=True) print(f"剧集ID: {episode_id}, 剧集名称: {episode_name}") print(f"总共抓取到{len(all_episode_containers)}集")
一些注意细节:
- IMDB的页面class名和API参数可能会不定期更新,如果代码跑不通了,记得打开开发者工具重新检查最新的元素结构和请求参数
- 记得保持
headers里的User-Agent和你浏览器的一致,不然可能会被IMDB限制访问 - 如果有不止一次的“加载更多”(比如剧集总数超过80集的情况),你可以循环检查是否还有更多按钮,或者循环请求AJAX直到返回空内容
备注:内容来源于stack exchange,提问作者Kasper Jcob
相关产品推荐
相关产品推荐

