无法从烂番茄在映影片页面爬取指定数据,请求技术支持
解决烂番茄动态页面爬取失败的问题
兄弟,我一眼就看出问题所在了——你用的request库只能抓取静态HTML,但烂番茄的「正在上映」页面是JavaScript动态渲染的!服务器返回的初始页面里根本没有你要的电影列表数据,所有内容都是浏览器加载JS后才生成的,所以cheerio找不到任何元素,循环自然没法执行。
下面给你两种可行的解决方案,从易到难:
方案一:用Puppeteer模拟真实浏览器爬取
Puppeteer是Chrome官方的无头浏览器工具,能完整复刻真实浏览器的页面渲染流程,完美解决动态页面爬取问题。
完整可运行代码
const puppeteer = require('puppeteer'); async function scrapeRottenTomatoes() { // 启动浏览器,配置反爬参数 const browser = await puppeteer.launch({ headless: 'new', // 新版无头模式,更贴近真实浏览器 args: [ '--no-sandbox', '--disable-setuid-sandbox', '--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' ] }); const page = await browser.newPage(); // 导航到目标页面,等待动态数据加载完成 await page.goto('https://www.rottentomatoes.com/browse/in-theaters/', { waitUntil: 'networkidle2' // 等待网络请求基本停止,确保数据加载完毕 }); // 在浏览器上下文里提取数据(和你在控制台写JS逻辑一样) const movies = await page.evaluate(() => { const movieCards = document.querySelectorAll('div[data-testid="movie-card"]'); return Array.from(movieCards).map(card => { // 提取各个字段 const title = card.querySelector('h3[data-testid="movie-title"]').textContent.trim(); const criticScore = card.querySelector('span[data-testid="critics-score"]')?.textContent.trim() || '暂无评分'; const audienceScore = card.querySelector('span[data-testid="audience-score"]')?.textContent.trim() || '暂无评分'; const releaseDate = card.querySelector('p[data-testid="movie-release-date"]').textContent.trim(); const detailUrl = card.querySelector('a[data-testid="movie-title-link"]').href; const posterUrl = card.querySelector('img[data-testid="movie-poster"]').src; return { title, criticScore, audienceScore, releaseDate, detailUrl, posterUrl }; }); }); // 输出爬取结果 console.log('成功获取电影数据:', movies); // 关闭浏览器 await browser.close(); } // 执行爬取函数 scrapeRottenTomatoes().catch(err => console.error('爬取出错:', err));
使用步骤
- 先安装依赖:
npm install puppeteer - 代码里已经配置了用户代理,模拟真实Chrome浏览器,降低被反爬识别的概率
waitUntil: 'networkidle2'确保页面所有动态资源加载完成后再提取内容,避免拿到空数据
方案二:直接调用烂番茄的API接口(进阶)
如果你追求更高的爬取效率,可以抓包找到烂番茄加载电影数据的API接口,直接请求接口获取JSON格式的数据,不用渲染整个页面。不过要注意:
- 烂番茄的API可能有请求头校验,需要模拟真实的
User-Agent和Referer - 接口地址可能会随时变动,需要自己抓包确认
示例代码(接口可能随网站更新失效)
const axios = require('axios'); async function scrapeViaAPI() { try { const response = await axios.get('https://www.rottentomatoes.com/api/private/v2.0/browse?limit=30&offset=0&type=in-theaters', { 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', 'Referer': 'https://www.rottentomatoes.com/browse/in-theaters/' } }); const movies = response.data.docs.map(movie => ({ title: movie.title, criticScore: movie.tomatoScore ? `${movie.tomatoScore}%` : '暂无评分', audienceScore: movie.audienceScore ? `${movie.audienceScore}%` : '暂无评分', releaseDate: movie.releaseDate, detailUrl: `https://www.rottentomatoes.com${movie.url}`, posterUrl: movie.posterUrl })); console.log('API爬取结果:', movies); } catch (err) { console.error('API请求失败:', err); } } scrapeViaAPI();
反爬注意事项
- 不要短时间内频繁请求,建议每次请求间隔1-2秒
- 尽量使用真实的用户代理,避免使用默认的爬虫UA
- 如果用Puppeteer调试,可以暂时关闭无头模式(把
headless: 'new'改成headless: false),直观看到页面加载情况
内容的提问来源于stack exchange,提问作者Joe Christopher
相关产品推荐
相关产品推荐

