使用Cheerio从页面中提取数据..格式如下。由于这些表可能有所不同,我如何动态解析它们?

问题描述 投票:0回答:1

我希望聪明的人可以帮助我了解所有这些数组、对象和循环......我已经经常遇到它们,但我只是不明白为什么没有一种简单的方法让我在 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(&quot;&quot;)" 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>

javascript html arrays loops cheerio
1个回答
0
投票

有很多方法可以做到这一点,但这里有一个递归方法可以帮助您入门:

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>
,如果有,则浸入该表格。它不处理表内有多个表的情况——留作练习,因为它可能不适用于您的用例。

© www.soinside.com 2019 - 2024. All rights reserved.