• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

桃七七和魔法球一键下载网页表格数据为 JSON 和 CSV

武飞扬头像
桃李实验室
帮助1

桃七七是个热爱运动的女程序员,她经常在 Sports Reference 这个网站上查看各类体育赛事的最新统计数据。

某天,想要对这些数据进行深入分析时,她发现该网站并未提供直接的下载功能。于是,她决定自己动手编写 JavaScript 代码,实现一键下载网页表格数据的功能。

这段代码的工作原理并不复杂,它会寻找页面上所有的表格元素,并在每个表格前添加两个按钮,一个用于将数据以 JSON 格式下载,另一个则以 CSV 格式下载。

点击这些按钮后,代码会读取表格中的数据,转换成所选格式并下载到本地设备。

第 01 章 分析表格结构

首先,桃七七需要获取页面上的表格数据。打开浏览器的开发者工具(F12),定位目标表格元素,她发现表格由 <table> 元素表示,包含多个 <tr> (行)和 <td> (单元格)元素,这就是她需要的数据。经过详细分析,她发现网站的表格元素结构高度统一:

  1. 表格标题:概括整个表格内容。
  2. 合并后的表格表头:通常作为标题的扩展部分。
  3. 普通的表格表头:可作为 JSON 对象的键(key)或 CSV 文件的列标识。
  4. 表格中的数据行:存储需要保存的实际数据。

学新通

经过深入检查,表格 <tbody> 的数据层次结构符合预期,主要由 <tr><td> 标签组成。

学新通

现在,桃七七有了清晰的理解和实现思路。

第 02 章 获取表格数据

桃七七需要合理利用表格的内容,将它们拆分出来保存为表格名和表格数据。

1. 创建表格名

桃七七首先将 caption 和 thead 中的内容提取出来,组装成文件名。要做到这一点,她编写了一个函数,如下:

function getFileName(table) {
  let caption = table.querySelector("caption").innerHTML;
  const regexMatch = /<span style[^>]*>([^<] )<\/span>/i.exec(caption);
  caption = (regexMatch && regexMatch[1] ? regexMatch[1] : "").trim();

  let title = table.querySelector("caption").innerText.trim();

  if (!title.includes(caption)) {
    title = `${title}__${caption}`;
  }

  return title.replace(/[^\w\s]/gi, "").replace(/\s /g, "_");
}

这个函数主要做了以下几件事情。

  1. 首先,它从 <caption> 标签中获取 HTML 内容,并尝试匹配一种特定格式的 <span> 标签。如果匹配成功,它会提取出该标签内的文本内容;否则,默认为空字符串。
  2. 然后,它获取 <caption> 标签的纯文本内容,并将其清理、修剪。
  3. 如果标题(即纯文本内容)中不包含前面提取的 <span> 标签内容(即 caption),那么在标题后面添加 "__" 和 caption。
  4. 最后,删除标题中所有非字母数字和空白字符,将连续的空白替换为单个下划线,并返回处理后的字符串作为文件名。

2. 将表格数据保存到数组中

然后,她编写了一个 JavaScript 函数,通过读取每个 <td> 元素的内容,收集表格中的所有数据。

function getTableData(tableId) {
  const table = document.getElementById(tableId);
  if (!table) {
    alert("暂不支持该表格");
    return;
  }

  const fileName = getFileName(table);

  const headersElements = Array.from(table.querySelectorAll("thead tr th"));
  let keys = headersElements.map((cell) => cell.dataset.stat);
  keys = keys.filter((item) => item);

  const rows = Array.from(table.querySelector("tbody").rows);

  const data = [];

  rows.forEach((row) => {
    const cells = Array.from(row.cells);

    let rowData = {};
    for (let i = 0; i < keys.length; i  ) {
      if (keys[i]) {
        rowData[keys[i]] = cells[i]?.textContent.trim() || null;
      }
    }

    data.push(rowData);
  });

  return { data, keys, fileName };
}

这个函数主要做了以下几件事情。

  1. 首先,它通过 getElementById 获取目标表格。如果找不到该表格,它会弹出警告并终止函数。
  2. 然后,它调用前面定义的 getFileName 函数为该表格生成一个文件名。
  3. 接着,它搜索表格的表头部分(<thead> 元素),获取所有的列标题(<th> 元素),并将它们映射到一个数组 keys 中。这个数组会过滤掉任何空值。
  4. 下一步,它遍历表格的每一行(<tr> 元素)并获取每个单元格(<td> 元素)的内容。对于每一行,它创建一个新的对象 rowData,其中键是表格的列标题,而值则是当前单元格的文本内容。
  5. 它把每一行的数据对象 rowData 添加到数据数组 data 中。
  6. 最后,它返回一个对象,包含了提取的数据、列标题以及文件名。

第 03 章 保存数据为JSON 和 CSV

在获取到数据后,桃七七编写了两个函数以将这些数据转化为 JSON 和 CSV 格式。

1. 创建公共函数

先创建了一个公共函数,它会生成一个 Blob 对象(此对象即为要保存的数据),然后创建一个 URL 指向该 Blob 对象,并模拟用户点击动作,以便下载并保存数据到本地文件。

下方是桃七七所编写的 JavaScript 代码:

function downloadData(content, fileName, mimeType) {
  const blob = new Blob([content], { type: mimeType });
  const url = URL.createObjectURL(blob);

  const a = document.createElement("a");
  a.href = url;
  a.download = `${fileName}`.replace(/[^\w\s]/gi, "");
  a.click();

  URL.revokeObjectURL(url);
}

这个函数主要用于处理和下载数据,其任务包括:

  1. 创建一个新的 Blob 对象,其中包含要下载的内容。
  2. 利用 URL.createObjectURL 方法为该 Blob 对象创建一个 URL。
  3. 创建并调用 <a> 元素的 click 方法来触发下载操作。
  4. 使用 URL.revokeObjectURL 方法释放由 URL.createObjectURL 创建的 URL。

2. 分别保存数据

接下来桃七七创建了两个函数:downloadDataAsJSONdownloadDataAsCSV,用于将获取的表格数据分别保存为 JSON 和 CSV 格式。

function downloadDataAsJSON(tableId) {
  const { data, fileName } = getTableData(tableId);
  const jsonString = JSON.stringify(data, null, 2);

  downloadData(jsonString, fileName, "application/json");
}

function downloadDataAsCSV(tableId) {
  const { data, keys, fileName } = getTableData(tableId);

  let csvContent = keys.join(",")   "\n";

  data.forEach((row) => {
    csvContent  = keys.map((key) => row[key]).join(",");
    csvContent  = "\n";
  });

  downloadData(csvContent, fileName, "text/csv");
}

downloadDataAsJSON 函数中,它将提取的数据转换为 JSON 字符串,并调用 downloadData 函数进行下载。

而在 downloadDataAsCSV 函数中,它创建一个 CSV 格式的字符串,包括列标题和每一行的数据,然后使用 downloadData 函数进行下载。

第 04 章 创建下载按钮

最后,桃七七编写代码,在每个表格前方添加两个下载按钮:一个用于下载 JSON 格式的数据,另一个用于下载 CSV 格式的数据。当点击这些按钮时,就会调用前面创建的函数,开始下载数据。

以下是桃七七编写的对应 JavaScript 代码:

const buttonStyle = `
  background-color: #DC2626;
  color: white;
  position: absolute;
  cursor: pointer;
  padding: 6px;
  font-size: 12px;
  top: 4px;
  z-index: 10;
  border: none;
  box-sizing: border-box;
`;

function insertButtons() {
  // 检查是否已经插入了
  if (document.querySelector(".sr-download-button")) {
    return;
  }

  const tables = document.querySelectorAll("table.stats_table");
  for (let i = 0; i < tables.length; i  ) {
    const table = tables[i];
    table.parentNode.style.position = "relative";
    table.parentNode.style.padding = "36px 0";
    const id = table.id;

    // Create JSON download button
    const jsonButton = document.createElement("button");
    jsonButton.setAttribute("class", "sr-download-button");
    jsonButton.setAttribute("style", `${buttonStyle} left: 0;`);
    jsonButton.innerText = "下载 JSON";

    jsonButton.onclick = function () {
      downloadDataAsJSON(id);
    };
    table.insertAdjacentElement("beforebegin", jsonButton);

    // Create CSV download button
    const csvButton = document.createElement("button");
    csvButton.setAttribute("class", "sr-download-button");
    csvButton.setAttribute(
      "style",
      `${buttonStyle} left: 80px; background-color: #4338CA;`
    );
    csvButton.innerText = "下载 CSV";

    csvButton.onclick = function () {
      downloadDataAsCSV(id);
    };
    table.insertAdjacentElement("beforebegin", csvButton);
  }
}

第 05 章 总结

打开控制台,将所有的代码贴到命令行,并运行一下创建按钮的函数。

insertButtons();

就会发现表格的左上方添加好了下载按钮。现在,桃七七可以快乐的下载自己想要的表格数据了。

学新通

完成以上步骤后,桃七七成功创建了一个小工具,可以方便地下载任意表格数据。如果你也遇到了类似的问题,不妨学习桃七七的方法,利用技术来解决问题。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgahiij
系列文章
更多 icon
同类精品
更多 icon
继续加载