Задать вопрос
@Gera01
Unity, С# и больше ничего.

Как искать значения не по номеру дочернего обьекта, а по значению title?

Добрый день! Брал значения ячеек по номеру дочернего обьекта, но так, как дочерние обьекты меняются местами - значения перемешиваются. И я решил получать значения по значению тайтл. Вот как это выглядело раньше:

Старый вариант
async function GetData(page){

  const data = await page.evaluate(() => {
    const result = [];
    const rows = document.querySelectorAll('#ctl00_m_g_d2dd5dba_7b4f_450f_a43b_fccfea58bc64_ctl00__grid_leftpane_mainTable > tbody tr');
    
    rows.forEach((row) => {

      const getTextFromCell = (row, selector) => {
        const cell = row.querySelector(selector);
        return cell ? cell.innerText : '';
      };
      const record = {
        id: getTextFromCell(row, 'td:nth-child(3) a'),
        date: getTextFromCell(row, 'td:nth-child(4)'),
        value: getTextFromCell(row, 'td:nth-child(5)'),
        weight: getTextFromCell(row, 'td:nth-child(8)'),
        yes: getTextFromCell(row, 'td:nth-child(2) a'),
        no: getTextFromCell(row, 'td:nth-child(4) span'),
        status: getTextFromCell(row, 'td:nth-child(6) span'),
        direction: getTextFromCell(row, 'td:nth-child(7) span'),
        manager: getTextFromCell(row, 'td:nth-child(8) span'),
        duration: getTextFromCell(row, 'td:nth-child(9) span'),
        comment: getTextFromCell(row, 'td:nth-child(10) span'),
        category: getTextFromCell(row, 'td:nth-child(11) span'),
        dateCreated: getTextFromCell(row, 'td:nth-child(12) span'),
        createdBy: getTextFromCell(row, 'td:nth-child(13) span'),
        dateModified: getTextFromCell(row, 'td:nth-child(14) span'),
        modifiedBy: getTextFromCell(row, 'td:nth-child(15) span'),
        source: getTextFromCell(row, 'td:nth-child(16) span'),
        destination: getTextFromCell(row, 'td:nth-child(17) span'),
        employee: getTextFromCell(row, 'td:nth-child(18) span'),
        project: getTextFromCell(row, 'td:nth-child(19) span'),
        department: getTextFromCell(row, 'td:nth-child(20) span'),
        location: getTextFromCell(row, 'td:nth-child(21) span'),
        tonnage: getTextFromCell(row, 'td:nth-child(22) span'),
        transportType: getTextFromCell(row, 'td:nth-child(4)'),
        tariff: getTextFromCell(row, 'td:nth-child(5)'),
        shipmentDate: getTextFromCell(row, 'td:nth-child(2) span'),
        client: getTextFromCell(row, 'td:nth-child(7)'),
        clientAddress: getTextFromCell(row, 'td:nth-child(8)'),
        driverPhone: getTextFromCell(row, 'td:nth-child(9)')
      };
      result.push(record);
    
    });

    return result;
  });
  
  return data;
}


Но после обновления кода - в консоль стал выходить массив, где все обьекты пустые. Как я понял - это потому, что getTextFromTitle - не находит не одной нужной тайтл и поэтому возвращяет ''. Вопрос в том - почему оно это делает и как это исправить?
Вот обновленный вариант кода:

Обновленный вариант
async function GetData(page){

  const data = await page.evaluate(() => {
    const result = [];
    const rows = document.querySelectorAll('#ctl00_m_g_d2dd5dba_7b4f_450f_a43b_fccfea58bc64_ctl00__grid_leftpane_mainTable > tbody tr');
    
    rows.forEach((row) => {

      const getTextFromTitle = (row, title) => {
        const cell = row.querySelector(`span[title="${title}"]`);
        return cell ? cell.innerText : '';
      };

      const record = {
        id: getTextFromTitle(row, 'Приказ'),
        date: getTextFromTitle(row, 'Дата составления'),
        value: getTextFromTitle(row, 'Значение'),
        weight: getTextFromTitle(row, 'Вес'),
        yes: getTextFromTitle(row, 'Да'),
        no: getTextFromTitle(row, 'Нет'),
        status: getTextFromTitle(row, 'Статус'),
        direction: getTextFromTitle(row, 'Направление'),
        manager: getTextFromTitle(row, 'Менеджер'),
        duration: getTextFromTitle(row, 'Продолжительность'),
        comment: getTextFromTitle(row, 'Комментарий'),
        category: getTextFromTitle(row, 'Категория'),
        createdBy: getTextFromTitle(row, 'Создал'),
        dateModified: getTextFromTitle(row, 'Дата изменения'),
        modifiedBy: getTextFromTitle(row, 'Изменил'),
        source: getTextFromTitle(row, 'Источник'),
        destination: getTextFromTitle(row, 'Назначение'),
        employee: getTextFromTitle(row, 'Сотрудник'),
        project: getTextFromTitle(row, 'Проект'),
        department: getTextFromTitle(row, 'Отдел'),
        location: getTextFromTitle(row, 'Местоположение'),
        tonnage: getTextFromTitle(row, 'Тоннаж'),
        transportType: getTextFromTitle(row, 'Тип транспорта'),
        tariff: getTextFromTitle(row, 'Тариф'),
        shipmentDate: getTextFromTitle(row, 'Дата отгрузки'),
        client: getTextFromTitle(row, 'Клиент'),
        clientAddress: getTextFromTitle(row, 'Адрес клиента'),
        driverPhone: getTextFromTitle(row, 'Телефон водителя')
      };
      result.push(record);
    
    });

    return result;
  });
  
  return data;
}


Еще большая проблема заключается в том, что названия тайтлов - такие же как и их значения. Это - ячейки таблицы и для меня был бы идеальным вариант брать значения каждой ячейке по столбцу. То есть есть столбец где одни значения и я по нему и прохожусь циклом. Можно ли такое сделать?
  • Вопрос задан
  • 46 просмотров
Подписаться Средний Комментировать
Решения вопроса 1
@Gera01 Автор вопроса
Unity, С# и больше ничего.
Решением стал следующий код:

const table = await page.$(cargoBoxSelector);
const headings = await table.$$eval('th', ths => ths.map(th => th.innerText));

await sleep(2000);

const rows = await table.$$eval('tr', trs =>
trs.slice(1).map(tr =>
Array.from(tr.querySelectorAll('td')).map(td => td.innerText)
)
);
console.log(headings);
console.log(rows);
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Невозможно сказать не увидев html. Вероятнее всего не правильный селектор. Могу предположить что ваши title у td, а не у span. Соответственно должно быть так: td[title="${title}"] span.

Но тут дело в другом - в том что вам в принципе приходится так делать. Похоже у вас проблемы с архитектурой самого приложения, так как задача строить объект js из данных вытаскиваемых из нод DOM страницы - один из индикаторов таких проблем. Вероятно не очень правильный выбор инструмента.
Вам стоит посмотреть в сторону реактивных фреймворков - таких как React или Vue.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы