如何用JavaScript结合Cheerio提取多子表数据并合并为单表
问题:提取Finviz日历页面的分组表格数据
我需要从Finviz日历页面下载完整表格数据,页面中table[class="calendar"]下有5个各自包含thead和tbody的子表。现有代码可提取所有表头和内容文本,但未按子表分组。我希望提取每个子表的表头与内容,再合并为与网页布局一致的完整表格,该如何实现?
现有代码
function test() { const url = "https://finviz.com/calendar.ashx"; const res = UrlFetchApp.fetch(url, { muteHttpExceptions: true, }).getContentText(); const $ = Cheerio.load(res); var thead = $("thead") .find("th") .toArray() .map(el => $(el).text()); var tableHead = [], column = 9; while (thead.length) tableHead.push(thead.splice(0, column)); //Convert 1D array to 2D array console.log(tableHead); var tcontents = $("body > div.content") .find("td") .toArray() .map(el => $(el).text()); var idx = tcontents.indexOf("No economic releases"); if (idx) tcontents.splice(idx + 1, 0, "", "", "", "", "", ""); // Add empty elemets to match number of table columns var tableContents = [], column = 9; while (tcontents.length) tableContents.push(tcontents.splice(0, column)); //Convert 1D array to 2D array tableContents.pop(); // remove last empty array console.log(tableContents); }
解决方案
核心思路是逐个遍历每个子表,单独提取每个子表的表头和对应内容,这样就能保证表头和内容的分组对应,最后再整合所有子表数据。
修改后的代码如下:
function test() { const url = "https://finviz.com/calendar.ashx"; const res = UrlFetchApp.fetch(url, { muteHttpExceptions: true, }).getContentText(); const $ = Cheerio.load(res); const allTables = []; // 遍历每个子表 $('table.calendar').each((_, table) => { const $table = $(table); const tableData = {}; // 提取当前子表的表头 const headers = $table.find('thead th').toArray().map(el => $(el).text().trim()); tableData.headers = headers; // 提取当前子表的内容行 const rows = []; $table.find('tbody tr').each((_, tr) => { const cells = $(tr).find('td').toArray().map(el => $(el).text().trim()); // 处理"No economic releases"的情况,补全列数 if (cells.includes("No economic releases")) { while (cells.length < headers.length) { cells.push(""); } } rows.push(cells); }); tableData.rows = rows; allTables.push(tableData); }); // 输出按子表分组的数据 console.log("按子表分组的完整数据:", allTables); // 如果需要合并成和网页一致的扁平化表格(表头+所有行) const mergedTable = []; allTables.forEach(table => { mergedTable.push(table.headers); mergedTable.push(...table.rows); }); console.log("合并后的完整表格:", mergedTable); }
关键修改说明
- 用
$('table.calendar').each()遍历每个子表,确保表头和内容一一对应 - 每个子表单独提取表头和内容,避免全局提取导致的分组混乱
- 在子表内部处理"No economic releases"的补列逻辑,更精准
- 最终可以同时得到按子表分组的数据和合并后的完整表格,满足不同需求
内容的提问来源于stack exchange,提问作者Newbie
相关产品推荐
相关产品推荐

