IMDb Top250电影爬虫仅爬取25条数据的问题排查与修复求助
IMDb Top250电影爬虫仅爬取25条数据的问题排查与修复求助
嘿,我来帮你搞定这个爬虫问题!你遇到的情况其实很常见,现在的现代网站为了优化加载速度,玩了不少“小心机”,咱们一步步拆解原因,再给你两个靠谱的修复方案。
问题原因分析
你现在只拿到25条数据,主要有两个核心问题:
动态生成的不稳定选择器
你用的sc-b189961a-0 hBZnfJ cli-children这类以sc-开头的class,是React/Vue这类前端框架自动生成的动态class,不仅可能只对应页面初始加载的前25条内容,而且IMDb每次更新前端代码,这个class名可能就变了,完全不适合用来做爬虫的选择器。懒加载机制
IMDb Top250页面用了懒加载策略:为了让页面打开更快,初始只渲染视口内的25条电影,剩下的225条需要你滚动页面时,才会通过JavaScript动态加载到页面里。而BeautifulSoup只能解析页面的初始静态HTML源码,它不会执行JavaScript,所以自然拿不到后续加载的内容。
修复方案
方案一:用Selenium模拟浏览器(最容易上手,稳定可靠)
这个方案是直接模拟真实用户的浏览行为,触发懒加载把所有250条内容都加载出来,再解析页面。步骤如下:
- 先安装Selenium:
pip install selenium
- 下载对应你浏览器的驱动(比如ChromeDriver,要和你的Chrome版本匹配),把它放到系统PATH里,或者在代码里指定路径。
- 替换你的代码为下面的版本:
import pandas as pd from selenium import webdriver import time from bs4 import BeautifulSoup # 初始化Chrome浏览器(如果驱动没在PATH里,要加executable_path参数,比如executable_path="chromedriver.exe") driver = webdriver.Chrome() url = "https://www.imdb.com/chart/top/?ref_=nv_mv_250" driver.get(url) # 模拟滚动页面,触发所有懒加载内容 last_scroll_height = driver.execute_script("return document.body.scrollHeight") while True: # 滚动到页面底部 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 等2秒让内容加载(可以根据你的网络情况调整) time.sleep(2) # 检查是否已经滚动到最底部 new_scroll_height = driver.execute_script("return document.body.scrollHeight") if new_scroll_height == last_scroll_height: break last_scroll_height = new_scroll_height # 现在页面已经加载了全部250条数据,获取完整的页面源码 html_doc = driver.page_source soup = BeautifulSoup(html_doc, "html.parser") # 用更稳定的选择器定位所有电影条目 # 这里用的是IMDb标记每条电影的稳定class,比动态class靠谱多了 movie_items = soup.find_all("li", class_="ipc-metadata-list-summary-item") print(len(movie_items)) # 现在输出应该是250了! # 最后记得关闭浏览器 driver.quit()
方案二:直接调用IMDb的AJAX接口(更高效,适合批量爬取)
如果你不想用浏览器模拟,还可以直接抓IMDb加载后续内容的AJAX接口,直接拿JSON格式的数据,比解析HTML效率高多了。
步骤如下:
- 打开IMDb Top250页面,按F12打开开发者工具,切换到Network标签,然后滚动页面,你会看到一个叫
data的XHR请求,地址是https://www.imdb.com/chart/top/data。 - 把这个请求的头信息复制下来(尤其是Cookie和User-Agent),然后用requests直接调用:
import requests import json headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Cookie': '这里放你浏览器里复制的Cookie内容', 'Accept': 'application/json, text/plain, */*' } # 直接请求数据接口 response = requests.get("https://www.imdb.com/chart/top/data", headers=headers) data = json.loads(response.text) # 所有250条电影的数据都在chartTitles字段里 movie_list = data['chartTitles'] print(len(movie_list)) # 输出250 # 你可以直接从这里提取电影名、评分、排名等信息,不用再解析HTML了 for movie in movie_list[:5]: print(f"排名:{movie['rank']},电影名:{movie['titleText']['text']}")
⚠️ 注意:IMDb的接口可能会有反爬验证,Cookie可能会过期,如果你发现请求失败,就去浏览器里重新复制最新的Cookie和请求头就行。
最后提醒
- 爬取IMDb数据时,要遵守他们的
robots.txt规则,不要太频繁地请求,避免被封IP。 - 尽量用稳定的选择器或者直接调用接口,少用动态生成的class,不然下次IMDb更新页面,你的爬虫又会失效。
备注:内容来源于stack exchange,提问作者Vu-Hoang Duong




