使用cheerio爬取网站时无法获取tbody、tr、td标签内容如何解决
问题原因
1. tbody标签的浏览器补全误区
你在浏览器F12开发者工具中看到的<tbody>标签,大概率是浏览器解析HTML时自动补全的,很多网站的原始静态HTML里,<table>标签下直接就是<tr>节点,并没有实际的<tbody>标签,你用cheerio解析原始HTML时自然查找不到该节点。
2. 目标站点数据动态渲染
你要爬取的cafef.vn行情页面的表格数据是前端异步请求接口后,通过JS动态渲染到页面的,你用request爬取到的初始静态HTML内容里,根本没有完整的#myTable表格结构,自然拿不到对应的tr、td内容。
排查步骤
先在你的现有代码中添加console.log(html)打印爬取到的原始页面内容,搜索内容是否存在id="myTable"的节点,以及该节点下是否有tbody、tr标签:
- 若能找到
#myTable节点,但没有tbody标签:直接删除代码中查找tbody的步骤即可 - 若找不到完整的
#myTable表格结构:确认是动态渲染场景,需要改用支持JS渲染的爬取工具
代码修复示例
静态场景(原始HTML存在表格结构)
const cheerio = require('cheerio'); const request = require('request-promise'); request('https://liveboard.cafef.vn/', (error, response, html) => { if (!error && response.statusCode == 200) { const $ = cheerio.load(html); const tab = $('#myTable') // 移除查找tbody的步骤,直接查找tr节点 const tr = tab.find('tr') for (var j = 0; j < tr.length; j++) { const contTr = $(tr[j]) console.log(contTr.text().trim()) const td = contTr.find('td') for (var i = 0; i < td.length; i++) { const contTd = $(td[i]) console.log(contTd.text()) } } } else { throw new Error(error) } })
动态渲染场景(原始HTML无表格结构)
改用支持JS渲染的puppeteer工具爬取,使用前需先执行npm install puppeteer安装依赖:
const puppeteer = require('puppeteer'); (async () => { // 启动浏览器 const browser = await puppeteer.launch(); const page = await browser.newPage(); // 访问目标页面,等待网络请求结束保证动态内容加载完成 await page.goto('https://liveboard.cafef.vn/', { waitUntil: 'networkidle2' }); // 在页面上下文内提取表格数据 const tableData = await page.evaluate(() => { const result = []; const trList = document.querySelectorAll('#myTable tbody tr'); trList.forEach(tr => { const row = []; const tdList = tr.querySelectorAll('td'); tdList.forEach(td => row.push(td.textContent.trim())); if (row.length) result.push(row); }); return result; }); // 输出结果 console.log(tableData); // 关闭浏览器 await browser.close(); })();
内容的提问来源于stack exchange,提问作者Duke
相关产品推荐
相关产品推荐

