TypeError: Cannot read property 'parent' of undefined错误,排查视频爬取代码问题
解决 TypeError: 无法读取未定义属性'parent' 的问题
咱们先拆解下这个错误的根源,再一步步修复你的爬虫代码:
错误原因分析
这个报错本质是cheerio的DOM操作对象未被正确初始化,导致后续调用DOM选择器时触发了深层的属性读取错误。具体来看你的代码,有几个关键问题:
- URL缺少协议头:你写的
url = "www.w3schools.com/html/html5_video.asp"没有https://前缀,request模块无法识别这是一个合法的HTTP请求地址,会直接请求失败,导致body为空,$ = cheerio.load(body)这行根本没执行,$变量保持undefined。 - 缺失错误处理逻辑:当
request请求出错(比如网络问题、URL无效)时,你没有处理err的情况,直接跳过了cheerio.load的步骤,后续执行$('source')时,相当于在undefined上调用方法,深层触发了读取parent属性的错误。 - 变量未声明:
$、links这些变量都没有用let/const声明,会变成全局变量,容易引发冲突。
修复后的完整代码
const request = require('request'); const cheerio = require('cheerio'); const url = "https://www.w3schools.com/html/html5_video.asp"; const VIDEO_LINKS = []; const VIDEO_LIST = []; function fillVideo(callback) { request(url, function(err, res, body) { // 先处理请求错误 if (err) { console.error('请求出错:', err); callback(err); // 把错误传递给回调 return; } // 检查响应状态码是否正常 if (res.statusCode !== 200) { console.error('响应状态异常:', res.statusCode); callback(new Error(`状态码: ${res.statusCode}`)); return; } // 确保body存在后再加载cheerio if (body) { const $ = cheerio.load(body); // 用const声明局部变量 const links = $('source'); // 声明局部变量 $(links).each(function(i, link) { const value = $(link).attr('src'); // 简化格式判断逻辑,先判断value是否存在 if (value && (value.endsWith('mp4') || value.endsWith('webm') || value.endsWith('ogv'))) { VIDEO_LINKS.push(value); VIDEO_LIST.push($(link).text()); } }); } callback(); }); } function writeVideo() { // 补全你的写入逻辑,比如输出到控制台或文件 console.log('抓取到的视频链接:', VIDEO_LINKS); console.log('视频文本:', VIDEO_LIST); } // 调用执行 fillVideo(function(err) { if (err) { console.error('抓取过程出错:', err); return; } writeVideo(); });
关键修复点说明
- 添加协议头:给URL加上
https://,确保request能正确发起请求。 - 完善错误处理:捕获请求错误、响应状态异常的情况,避免后续代码在非法状态下执行。
- 变量局部化:用
const/let声明所有变量,避免全局污染。 - 增强格式判断:先判断
value是否存在,再调用endsWith方法,避免value为undefined时的额外报错。
内容的提问来源于stack exchange,提问作者jewstin
相关产品推荐
相关产品推荐

