如何从HTML表格的span元素提取数据生成目标JSON结构
问题:从HTML表格的span元素提取数据生成指定JSON结构
已成功获取表格的innerHTML,console.log(items)输出如下:
{"innerHTML":"<thead><tr><th class=\"text-center\"><i class=\"fas fa-edit\" id=\"\" style=\"font-size: 16px; opacity: 0.25\"></i></th><th class=\"text-center\"><i class=\"fas fa-print\" id=\"\" style=\"font-size: 16px; opacity: 0.25\"></i></th><th class=\"text-center w-px whitespace-nowrap\"><a href=\"/customers?Take=50&amp;SortBy=0&amp;Desc=True&amp;FileID=VGVzdA\" class=\"text-neutral-500 hover:text-neutral-500 text-shadow dark:text-slate-400 dark:hover:text-slate-400 dark:text-shadow-none\">Code</a></th><th class=\"\"><a href=\"/customers?Take=50&amp;SortBy=1&amp;FileID=VGVzdA\" class=\"text-neutral-500 hover:text-neutral-500 text-shadow dark:text-slate-400 dark:hover:text-slate-400 dark:text-shadow-none\">Name</a></th><th class=\"\"><a href=\"/customers?Take=50&amp;SortBy=3&amp;FileID=VGVzdA\" class=\"text-neutral-500 hover:text-neutral-500 text-shadow dark:text-slate-400 dark:hover:text-slate-400 dark:text-shadow-none\">zone</a></th><th class=\"text-center w-px whitespace-nowrap\"><a href=\"/customers?Take=50&amp;SortBy=4&amp;Desc=True&amp;FileID=VGVzdA\" class=\"text-neutral-500 hover:text-neutral-500 text-shadow dark:text-slate-400 dark:hover:text-slate-400 dark:text-shadow-none\">Invoices</a></th><th class=\"text-right w-px whitespace-nowrap\"><a href=\"/customers?Take=50&amp;SortBy=8&amp;Desc=True&amp;FileID=VGVzdA\" class=\"text-neutral-500 hover:text-neutral-500 text-shadow dark:text-slate-400 dark:hover:text-slate-400 dark:text-shadow-none\">Accounts receivable</a></th></tr></thead><tbody><tr><td style=\"width: 1px\"><a href=\"/customer-form?Key=39cb2507-d07f-4357-987f-4451feee7b23&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\" class=\"bg-white border border-neutral-300 text-neutral-700 rounded py-1 px-4 hover:border-neutral-400 hover:text-neutral-800 hover:no-underline hover:bg-neutral-100 hover:shadow-inner dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700\" style=\"font-size: 11px\">Edit</a></td><td style=\"width: 1px\"><a href=\"/customer-view?Key=39cb2507-d07f-4357-987f-4451feee7b23&amp;Position=1&amp;MaxPosition=3&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\" class=\"bg-white border border-neutral-300 text-neutral-700 rounded py-1 px-4 hover:border-neutral-400 hover:text-neutral-800 hover:no-underline hover:bg-neutral-100 hover:shadow-inner dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700\" style=\"font-size: 11px\">View</a></td><td class=\"content text-center w-px whitespace-nowrap\"><span>D001</span></td><td class=\"content \"><span>customer 1</span></td><td class=\"content \"><span>A1</span></td><td class=\"content text-center w-px whitespace-nowrap\"><span style=\"font-weight: bold\"><a href=\"/sales-invoices?Customer=39cb2507-d07f-4357-987f-4451feee7b23&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\">3</a></span></td><td class=\"content observer:blur-sm observer:hover:blur-none observer:hover:transition text-right w-px whitespace-nowrap\"><span style=\"font-weight: bold\"><a href=\"/customer-transactions?Customer=39cb2507-d07f-4357-987f-4451feee7b23&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\">$ 130.00</a></span></td></tr><tr><td style=\"width: 1px\"><a href=\"/customer-form?Key=787cf96e-3267-453c-868f-03f4ad452a3e&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\" class=\"bg-white border border-neutral-300 text-neutral-700 rounded py-1 px-4 hover:border-neutral-400 hover:text-neutral-800 hover:no-underline hover:bg-neutral-100 hover:shadow-inner dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700\" style=\"font-size: 11px\">Edit</a></td><td style=\"width: 1px\"><a href=\"/customer-view?Key=787cf96e-3267-453c-868f-03f4ad452a3e&amp;Position=2&amp;MaxPosition=3&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\" class=\"bg-white border border-neutral-300 text-neutral-700 rounded py-1 px-4 hover:border-neutral-400 hover:text-neutral-800 hover:no-underline hover:bg-neutral-100 hover:shadow-inner dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700\" style=\"font-size: 11px\">View</a></td><td class=\"content text-center w-px whitespace-nowrap\"><span>D002</span></td><td class=\"content \"><span>customer 2</span></td><td class=\"content \"><span>B2</span></td><td class=\"content text-center w-px whitespace-nowrap\"><span style=\"font-weight: bold\"><a href=\"/sales-invoices?Customer=787cf96e-3267-453c-868f-03f4ad452a3e&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\">1</a></span></td><td class=\"content observer:blur-sm observer:hover:blur-none observer:hover:transition text-right w-px whitespace-nowrap\"><span style=\"font-weight: bold\"><a href=\"/customer-transactions?Customer=787cf96e-3267-453c-868f-03f4ad452a3e&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\">$ 223.75</a></span></td></tr><tr><td style=\"width: 1px\"><a href=\"/customer-form?Key=cdb7ee28-3c2a-4b50-b421-3c42a7bbcd02&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\" class=\"bg-white border border-neutral-300 text-neutral-700 rounded py-1 px-4 hover:border-neutral-400 hover:text-neutral-800 hover:no-underline hover:bg-neutral-100 hover:shadow-inner dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700\" style=\"font-size: 11px\">Edit</a></td><td style=\"width: 1px\"><a href=\"/customer-view?Key=cdb7ee28-3c2a-4b50-b421-3c42a7bbcd02&amp;Position=3&amp;MaxPosition=3&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\" class=\"bg-white border border-neutral-300 text-neutral-700 rounded py-1 px-4 hover:border-neutral-400 hover:text-neutral-800 hover:no-underline hover:bg-neutral-100 hover:shadow-inner dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700\" style=\"font-size: 11px\">View</a></td><td class=\"content text-center w-px whitespace-nowrap\"><span>D003</span></td><td class=\"content \"><span>customer 3</span></td><td class=\"content \"><span>B1</span></td><td class=\"content text-center w-px whitespace-nowrap\"><span style=\"font-weight: bold\"><a href=\"/sales-invoices?Customer=cdb7ee28-3c2a-4b50-b421-3c42a7bbcd02&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\">-</a></span></td><td class=\"content observer:blur-sm observer:hover:blur-none observer:hover:transition text-right w-px whitespace-nowrap\"><span style=\"font-weight: bold\"><a href=\"/customer-transactions?Customer=cdb7ee28-3c2a-4b50-b421-3c42a7bbcd02&amp;FileID=VGVzdA&amp;Referrer=L2N1c3RvbWVycz9Ta2lwPTAmVGFrZT01MCZGaWxlSUQ9VkdWemRB\">- $ 60.00</a></span></td></tr><tr><th></th><th></th><th></th><th></th><th></th><th class=\"observer:blur-sm observer:hover:blur-none observer:hover:transition font-semibold text-neutral-500 text-shadow text-center w-px whitespace-nowrap\"><div>4</div></th><th class=\"observer:blur-sm observer:hover:blur-none observer:hover:transition font-semibold text-neutral-500 text-shadow text-right w-px whitespace-nowrap\"><div>$ 293.75</div></th></tr></tbody>"}
尝试的代码
const url = 'http://127.0.0.1:55667/customers?FileID=VGVzdA' var x = document.querySelector("#printable-content > table:nth-child(1) > thead > tr:nth-child(1) > td > table:nth-child(2) > tbody > tr > td:nth-child(1) > div:nth-child(1) > b:nth-child(1)").textContent; fetch(url).then(function (response) { return response.text(); }).then(function (html) { // Convert the HTML string into a document object var parser = new DOMParser(); var doc = parser.parseFromString(html, 'text/html'); var y = doc.querySelector("#table > div.overflow-x-auto.lg\:overflow-visible.no-scrollbar > table").innerHTML; // Getting data from spans myObj = {innerHTML:"yyy"}; myObj.innerHTML = y; items = JSON.stringify(myObj); console.log(items); }).catch(function (err) { // There was an error alert('Something went wrong.', err); });
期望的JSON结构
{ "data": [ "D001", "customer 1", "A1", "4", "$ 155.00", "D002", "customer 2", "B2", "1", "$ 223.75", "D003", "customer 3", "B1", "-", "- $ 60.00" ] }
解决方案
无需先将innerHTML转为JSON再处理,直接在解析后的文档对象上操作即可。修改后的代码会遍历表格tbody行,跳过最后一行汇总行,提取每行的span文本并整理成目标结构:
const url = 'http://127.0.0.1:55667/customers?FileID=VGVzdA' fetch(url).then(function (response) { return response.text(); }).then(function (html) { // 解析HTML为文档对象 var parser = new DOMParser(); var doc = parser.parseFromString(html, 'text/html'); // 获取表格的tbody元素 const tbody = doc.querySelector("#table > div.overflow-x-auto.lg\\:overflow-visible.no-scrollbar > table tbody"); // 获取tbody里的所有行,排除最后一行汇总行 const rows = tbody.querySelectorAll('tr:not(:last-child)'); const data = []; rows.forEach(row => { // 获取当前行里的所有span元素 const spans = row.querySelectorAll('span'); spans.forEach(span => { // 提取span的文本内容并添加到data数组 data.push(span.textContent.trim()); }); }); // 生成目标JSON结构 const result = { data: data }; console.log(JSON.stringify(result, null, 2)); }).catch(function (err) { alert('Something went wrong.', err); });
说明
- 直接在解析后的文档对象上查询元素,避免重复处理innerHTML字符串。
- 使用
tr:not(:last-child)排除最后一行汇总行(该行无span元素,内容在div中)。 - 遍历每行的span元素,提取文本并整理到数组中,最后包装成目标JSON结构。
内容的提问来源于stack exchange,提问作者FoodHunter
相关产品推荐
相关产品推荐

