NodeJS: Как я могу скрепить две разные таблицы, которые визуально являются частью одной и той же таблицы, в один объект JSON? - PullRequest
0 голосов
/ 15 ноября 2018

Вот пример таблицы данных, которую я собираю:

Sample Table

Элементы красного цвета находятся в тегах <th>, в то время как элементы зеленого цвета находятся в теге <td>, тег <tr> может отображаться в зависимости от того, как они сгруппированы (т.е. собственный <tr>; фрагмент HTML:

РЕДАКТИРОВАТЬ: я забыл добавить окружающий div

<div class="table-cont">
    <table class="tg-1">
        <thead>
            <tr>
                <th class="tg-phtq">ID</td>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td class="tg-0pky">1</td>
                <td class="tg-0pky">2</td>
                <td class="tg-0pky">3</td>
            </tr>
        </tbody>
    </table>
    <table class="tg-2">
        <thead>
            <tr>
                <th class="tg-phtq">Sample1</td>
                <th class="tg-phtq">Sample2</td>
                <...the rest of the table code matches the pattern...>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td class="tg-0pky">Swimm</td>
                <td class="tg-dvpl">1:30</td>
                <...>
            </tr>
        </tbody>
        <...the rest of the table code...>
    </table>
</div>

Как вы можете видеть, в HTML это фактически две разные таблицы, а в приведенном выше примере они отображаются только как одна. Я хочу сгенерировать объект JSON, в котором keys и values включают данные из двух таблиц, как если бы они были одной, и вывести один объект JSON.

Как я сейчас это делаю, это немного модифицированный код JavaScript, который я нашел в учебнике:

РЕДАКТИРОВАТЬ: ниже я пытался найти способ выбрать все соответствующие теги <th> из обеих таблиц и вставить их в тот же массив, что и остальные массивы тегов <th>, и сделать то же самое для <tr> в теле таблицы; Я вполне уверен, что th я могу просто вставить элемент отдельно перед остальными, но только потому, что есть один - у меня возникли проблемы с выяснением, как это сделать для обоих массивов, и чтобы убедиться, что все элементы в два массива корректно отображаются друг на друга

РЕДАКТИРОВАТЬ 2: Возможное решение? Я пытался использовать XPath Selectors, и я могу использовать их в devTools, чтобы выбрать все, что я хочу, но page.evaluate не принимает их и page.$x('XPath') возвращает JSHandle@node поскольку я пытаюсь создать массив, но я не знаю, куда идти дальше

let scrapeMemberTable = async (page) => {
 await page.evaluate(() => {
  let ths = Array.from(document.querySelectorAll('div.table-cont > table.tg-2 > thead > tr > th'));
  let trs = Array.from(document.querySelectorAll('div.table-cont > table.tg-2 > tbody > tr'));
  // the above two lines of code are the main problem area- I haven't been 
  //able to select all the head/body elements I want in just those two lines of code
 // just removig the table id "tg-2" seems to deselect the whole thing
  const headers = ths.map(th => th.textContent);

  let results = [];

  trs.forEach(tr => {
      let r = {};            
      let tds = Array.from(tr.querySelectorAll('td')).map(td => td.textContent);

      headers.forEach((k,i) => r[k] = tds[i]);
      results.push(r);
  });

  return results; //results is OBJ in JSON format
 }
}

     ...

results = results.concat(            //merge into one array OBJ
        await scrapeMemberTable(page)
    );

     ...

Намеченный результат:

[
    {
        "ID": "1",                            <-- this is the goal
        "Sample1": "Swimm",
        "Sample2": "1:30",
        "Sample3": "2:05",
        "Sample4": "1:15",
        "Sample5": "1:41"
    }
]

Фактический результат:

[
    {
        "Sample1": "Swimm",
        "Sample2": "1:30",
        "Sample3": "2:05",
        "Sample4": "1:15",
        "Sample5": "1:41"
    }
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...