Консоль узла.вход в большой массив показывает «… еще 86 элементов»

#javascript #node.js #google-chrome #puppeteer

#javascript #node.js #google-chrome #кукловод

Вопрос:

Я новичок в puppeteer. Раньше у меня были PhantomJS и CasperJS, но при настройке более нового сервера (freebsd 12) выяснилось, что поддержка PhantomJS пропала, а CasperJS выдает ошибки сегментации.

Я смог отлично перенести свои приложения на puppeteer, но столкнулся с проблемой, что, когда я хочу захватить данные из таблицы, эти данные кажутся неполными или усеченными.

Мне нужна вся информация из таблицы, но в итоге всегда получается меньше.

Я пробовал таблицы меньшего размера, но они также получаются усеченными. Я не знаю, можно ли расширить console.log буфер или нет, или если есть лучший способ получить значения всех tds в таблице.

 const data = await page.$$eval('table.dtaTbl tr td', tds => tds.map((td) => {
    return td.innerHTML;
}));

console.log(data); 
  

Я должен быть в состоянии получить все строки, но вместо этого я получаю это

 [ 'SF xx/xxxx 3-3999 06-01-16',
'Sample text - POLE',
  '',

 /* tons of other rows (removed by me in this example) <- */

  '',

 /* end of output */ ... 86 more items ]
  

Мне нужны 86 других элементов!!!
потому что я заставляю PHP извлекать это из стандартного вывода по мере выполнения кода.

Ответ №1:

Почему console.log не работает

Под капотом console.log используется util.inspect , который выдает выходные данные, предназначенные для отладки. Чтобы создать разумную отладочную информацию, эта функция усечет вывод, который был бы слишком длинным. Процитировать документы:

Метод util.inspect() возвращает строковое представление объекта, предназначенное для отладки. Выходные данные util.inspect могут измениться в любое время и не должны зависеть от программного обеспечения.


Решение: использовать process.stdout

Если вы хотите записать выходные данные в stdout вы можете использовать process.stdout который является доступным для записи потоком. Это не изменит / усечет то, что вы пишете в потоке. Вы можете использовать его следующим образом:

 process.stdout.write(JSON.stringify(data)   'n');
  

Я добавил разрыв строки в конце, поскольку функция не будет сама создавать разрыв строки (в отличие от console.log ). Если ваш скрипт не полагается на него, вы можете просто удалить его.

Комментарии:

1. @ThomasDondorf @JohnRalston FWIW, это console.log() поведение касается прямого вывода объекта, строки не должны быть усечены, поэтому console.log((JSON.stringify(data)) может быть достаточно.

2. @vsemozhetbyt Да, это тоже должно сработать. Но я бы предпочел записывать в поток напрямую, вместо того, чтобы полагаться на функцию, которая говорит, что «не должна зависеть от программного обеспечения». Или есть какое-то преимущество в использовании console.log ?

3. @ThomasDondorf Я полагаю, что нет никакого преимущества, кроме простоты.

4. Ошибка неперехваченной ссылки: процесс не определен. почему? пожалуйста, направьте меня.

5. если вы хотите сохранить цвета, которые console.log() предоставляет, контролируя при этом, как усекаются ваши данные, вы можете использовать process.stdout.write(util.inspect(mydata, {colors: true, depth: 5, maxArrayLength: 20}))

Ответ №2:

Вы также можете использовать

 console.log(JSON.stringify(data, null, 4)); 
  

вместо

 process.stdout.write(JSON.stringify(data)   'n');
  

Ответ №3:

Я знаю, что вопрос задан пару лет назад, но это была проблема, с которой я сталкивался снова и снова. Обнаружение (через этот поток) базового util.inspect вызова помогло мне преодолеть эту проблему следующим образом:

 process.stdout.write(`${util.inspect(data, { maxArrayLength: 1000 })}n`)
  

По умолчанию maxArrayLength равен 100, поэтому данные усекаются для более длинных массивов.

Комментарии:

1. maxArrayLength: null чтобы удалить любое ограничение.

Ответ №4:

Вам обязательно нужно использовать stdout ? Не рекомендуется делать это для мониторинга, потому что stdout очень легко переполнить буфер (или получить неполный вывод) — как вы видели, иллюстрирующий проблему.

Почему бы не модифицировать PHP-скрипт для чтения из файла в виде потока с помощью readfile функции и записи в этот поток из вашего JS-кода с помощью fs ?

Комментарии:

1. спасибо за ваш ответ, когда я начинал с phantomjs, я обычно записывал в файл, а затем анализировал его php, как вы описали. Позже я объединил оба в один шаг. Я вернусь к этому, я надеялся, что есть способ распечатать весь innerhtml во время выполнения скрипта. еще раз спасибо