我希望聪明的人可以帮助我了解所有这些数组、对象和循环......我已经经常遇到它们,但我只是不明白为什么没有一种简单的方法让我在 DOM 上进行选择我想要抓取什么,然后将其作为 JSON 对象导出到 JS 变量。
我在这里想做的就是导出到这种格式的 JSON 字符串。
创建th:创建td 客户端 th : 客户端 td 业主 th : 业主 td
这就是表 ONE 的摘录
表二更复杂:
这里可以有无限的trs......这是我需要一个循环来确保所有文本内容从JS放入JSON的地方。
标题第 内容 声明日: 日期 说明 成本付款余额......此处所有这些行都可以是无限的。 th 和 tds 很明确,但 trs 的数量可以无限
每个标题都有一个内容(对于内容值,只需加入 div 中的所有值)。 每个标题还有一个可以包含多行的语句。它的变量。
因此表和页面中的列不会更改,但第二个表和迷你语句的行可以更改。第一个表中的数据是静态的。
我希望这是一个快速循环,可以将其解析为 JSON 对象,以便我可以发布到我的数据库?
<table class="summary">
<tbody><tr>
<th>Created</th>
<th>Client</th>
<th>Owner</th>
<th>Ref</th>
<th>Email Address</th>
<th>Postal Address</th>
</tr>
<tr>
<td>Created</td>
<td>Client</td>
<td>Owner</td>
<td>Ref</td>
<td>Email</td>
<td>Postal Address</td>
</tr>
</tbody></table>
<hr>
<table>
<tbody><tr>
<th>Title</th>
<th>Content</th>
<th>Statement</th>
</tr>
<tr>
<td>
<div>
<a class="packageTitle" onclick="openPackageDetail("")" title="Click for detail">{TITLE}</a>
</div>
</td>
<td>
<div>
<div>
{CONTENT1}
</div>
<div class="lighter smaller">Containing:</div>
<div>
<div class="smaller">
Early Bird Guest (1)
</div>
</div>
</div>
</td>
<td>
<table class="smaller statement">
<tbody><tr>
<th>Date</th>
<th>Description</th>
<th style="padding-right:1em">Cost</th>
<th style="padding-right:1em">Payment</th>
<th>Balance</th>
</tr>
<tr>
<td>dATE AND TIME</td>
<td>DESCRIPTION</td>
<td>COST</td>
<td>PAYMENT</td>
<td>BALANCE</td>
</tr>
<tr>
<td>DATE</td>
<td>DESCRIPTION</td>
<td>COST</td>
<td>PAYMENT</td>
<td>BALANCE</td>
</tr>
</tbody></table>
</td>
</tr>
</tbody></table>
</div>
有很多方法可以做到这一点,但这里有一个递归方法可以帮助您入门:
const cheerio = require("cheerio"); // 1.0.0-rc.12
const html = `<Your HTML copy-pasted from question>`;
const parseTables = root => {
const headers = [...$(root).find("> tbody > tr > th")].map(
th => $(th).text().trim()
);
return [...$(root).find("> tbody > tr:has(td)")].map(tr =>
Object.fromEntries(
[...$(tr).find("> td")].map((td, i) => {
if ($(td).find("> table").length === 1) {
return [
headers[i],
parseTables($(td).find("> table").get(0)),
];
}
return [headers[i], $(td).text().trim()];
})
)
);
};
const $ = cheerio.load(html);
const data = [...$("body > table")].map(parseTables);
require("util").inspect.defaultOptions.depth = null;
console.log(data);
输出:
[
[
{
Created: 'Created',
Client: 'Client',
Owner: 'Owner',
Ref: 'Ref',
'Email Address': 'Email',
'Postal Address': 'Postal Address'
}
],
[
{
Title: '{TITLE}',
Content: '{CONTENT1}\n' +
' Containing:\n' +
' \n' +
' Early Bird Guest (1)',
Statement: [
{
Date: 'dATE AND TIME',
Description: 'DESCRIPTION',
Cost: 'COST',
Payment: 'PAYMENT',
Balance: 'BALANCE'
},
{
Date: 'DATE',
Description: 'DESCRIPTION',
Cost: 'COST',
Payment: 'PAYMENT',
Balance: 'BALANCE'
}
]
}
]
]
这是通过进行相当正常的表格抓取来实现的,但测试
<td>
内部是否有 <table>
,如果有,则浸入该表格。它不处理表内有多个表的情况——留作练习,因为它可能不适用于您的用例。