Puppeteer获取div.appname文本失败,遇TypeError空值错误求助
解决Puppeteer获取七麦数据
.appname文本时的TypeError问题 我来帮你排查并解决这个问题,你遇到的TypeError: Cannot read property 'innerHTML' of null(或代码中涉及的innerText)本质是尝试访问不存在元素的属性,下面是具体的问题分析和修复方案:
问题根源拆解
- 元素范围定位错误:你遍历的是
.data-table > tbody > tr > td,但表格里的<td>承担不同功能(排名、图标、名称、下载量等),只有特定位置的<td>包含.appname元素。直接遍历所有<td>会拿到大量不含目标元素的节点,导致content.$("div.appname")返回null,后续访问属性就触发报错。 - 页面加载时机未同步:点击
freeButton后页面会重新渲染免费榜单,但你没有等待新的DOM加载完成就去获取元素,可能拿到旧页面的残留节点或未完全渲染的DOM。 - 选择器精度不足:宽泛的选择器会引入无效节点,增加报错概率。
修复后的完整代码
const puppeteer = require("puppeteer"); (async function main() { try { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); // 使用更贴近现代浏览器的UA,降低反爬识别概率 await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"); // 访问目标页面,等待DOM完全加载 await page.goto("https://www.qimai.cn/rank/index/brand/all/genre/6014/device/iphone/country/us/date/2019-03-19", { waitUntil: 'domcontentloaded', timeout: 0 }); // 等待免费按钮可见后点击,同时等待页面导航完成 const freeButton = await page.waitForSelector('[href="/rank/index/brand/free/device/iphone/country/us/genre/6014/date/2019-03-19"]', { visible: true }); await Promise.all([ freeButton.click(), page.waitForNavigation({ waitUntil: 'domcontentloaded' }) // 确保页面渲染完成后再操作 ]); // 等待数据表格行加载完成,定位到包含app信息的行 await page.waitForSelector(".data-table tbody tr", { visible: true }); const appRows = await page.$$(".data-table tbody tr"); for (const row of appRows) { // 在当前行内精准定位.appname元素 const appNameElement = await row.$("td div.appname"); if (appNameElement) { // 先判断元素是否存在,避免报错 const gameName = await page.evaluate(el => el.innerText.trim(), appNameElement); console.log("Game Name: ", gameName); } } console.log("-- bingo --"); // 调试完成后可打开该行关闭浏览器 // await browser.close(); } catch (e) { console.log("Error occurred: ", e); } })();
关键优化说明
- 同步页面导航状态:用
Promise.all同时执行点击和等待页面导航,确保页面完全渲染后再操作DOM,避免拿到未更新的节点。 - 缩小元素定位范围:遍历表格行(
<tr>)而非所有<td>,在每行内查找目标元素,减少无效遍历。 - 添加元素存在性校验:访问元素属性前先判断
appNameElement是否为null,从根源避免TypeError。 - 更新User-Agent:使用更现代的UA字符串,降低被七麦反爬机制拦截的概率。
额外注意事项
七麦数据有反爬机制,频繁访问可能被限制,建议:
- 在操作之间添加适当延迟(如
await page.waitForTimeout(1000)) - 避免短时间内重复运行脚本
- 必要时可使用代理IP规避限制
内容的提问来源于stack exchange,提问作者Koh Shuan Jin
相关产品推荐
相关产品推荐

