You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

IMDb Top250电影爬虫仅爬取25条数据的问题排查与修复求助

IMDb Top250电影爬虫仅爬取25条数据的问题排查与修复求助

嘿,我来帮你搞定这个爬虫问题!你遇到的情况其实很常见,现在的现代网站为了优化加载速度,玩了不少“小心机”,咱们一步步拆解原因,再给你两个靠谱的修复方案。

问题原因分析

你现在只拿到25条数据,主要有两个核心问题:

  1. 动态生成的不稳定选择器
    你用的sc-b189961a-0 hBZnfJ cli-children这类以sc-开头的class,是React/Vue这类前端框架自动生成的动态class,不仅可能只对应页面初始加载的前25条内容,而且IMDb每次更新前端代码,这个class名可能就变了,完全不适合用来做爬虫的选择器。

  2. 懒加载机制
    IMDb Top250页面用了懒加载策略:为了让页面打开更快,初始只渲染视口内的25条电影,剩下的225条需要你滚动页面时,才会通过JavaScript动态加载到页面里。而BeautifulSoup只能解析页面的初始静态HTML源码,它不会执行JavaScript,所以自然拿不到后续加载的内容。

修复方案

方案一:用Selenium模拟浏览器(最容易上手,稳定可靠)

这个方案是直接模拟真实用户的浏览行为,触发懒加载把所有250条内容都加载出来,再解析页面。步骤如下:

  1. 先安装Selenium:
pip install selenium
  1. 下载对应你浏览器的驱动(比如ChromeDriver,要和你的Chrome版本匹配),把它放到系统PATH里,或者在代码里指定路径。
  2. 替换你的代码为下面的版本:
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效率高多了。
步骤如下:

  1. 打开IMDb Top250页面,按F12打开开发者工具,切换到Network标签,然后滚动页面,你会看到一个叫data的XHR请求,地址是https://www.imdb.com/chart/top/data
  2. 把这个请求的头信息复制下来(尤其是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

火山引擎 最新活动