#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 во время выполнения скрипта. еще раз спасибо