Puppeteer爬取表格时如何在箭头函数执行过程中过滤列数不足的行
Puppeteer爬取表格避免二次遍历过滤无效行的解决方案
问题背景
我正在使用Node的Puppeteer库爬取某网站的表格。
在爬取过程中,程序会返回两个数组,一个包含目标表格的所有行列数据,另一个数组仅包含表格的第一列,暂时无法定位问题触发原因也无法修复。
原有实现的缺陷
我最初使用的表格爬取代码如下:
var result = await page.$$eval('tbody > tr', rows => { return Array.from(rows, row => { const columns = row.querySelectorAll('td'); const arr = Array.from(columns, column => column.innerText); if (arr.length <= 1) { return; } return arr; }); });
上述代码试图在返回结果中过滤无效表格数据,但直接return会在数组中生成null值,导致数组长度翻倍,不符合预期。
目前我可以通过额外遍历过滤null值:
var filtered = result.filter(function (el) { return el != null; });
但这种二次遍历的方式会让程序执行耗时翻倍,我的需求是:如何直接过滤掉列数小于等于1的行,避免二次遍历?
最终解决方案
方案一:单次遍历同时完成转换与过滤
使用reduce方法替代Array.from的映射逻辑,单次遍历就完成合格行的筛选和内容转换,不需要后续二次过滤:
var result = await page.$$eval('tbody > tr', rows => { return Array.from(rows).reduce((acc, row) => { const columns = row.querySelectorAll('td'); const arr = Array.from(columns, column => column.innerText); if (arr.length > 1) { acc.push(arr); } return acc; }, []); });
最优方案:从源头锁定目标表格(根本解决)
直接通过ID选择器限定目标表格,从元素获取阶段就排除不需要的无效表格行,不需要额外做列数判断,性能最好:
var result = await page.$$eval('table#filter--result-table-resumo > tbody > tr', rows => { return Array.from(rows, row => { const columns = row.querySelectorAll('td'); return Array.from(columns, column => column.innerText); }); });
内容的提问来源于stack exchange,提问作者Nickolas de Luca Alberton
相关产品推荐
相关产品推荐

