Puppeteer - довольно классная библиотека Node.js. Разработанный командой Google Chrome, он предоставляет вам инструменты для простого управления браузером Chromium или Chrome без заголовка для анализа веб-страниц и автоматизации функций веб-браузера. Потратив немного времени на изучение синтаксиса, я решил, что для моего первого крупного приложения, использующего Puppeteer, я хотел бы использовать его вместе с ElectronJS для создания настольного приложения для очистки веб-страниц, которое автоматизирует задачу, которая в то время выполнялась вручную с помощью члены моей команды на работе. Однако позже я обнаружил, что для совместной работы Puppeteer и Electron может потребоваться немного творчества. Я пишу эту статью в надежде, что любой, кто столкнется с той же проблемой, что и я, сможет воспользоваться решением, которое я представляю ниже.
Я не собираюсь вдаваться в подробности своей программы или предоставлять руководство по веб-парсеру с помощью Puppeteer, но основная суть созданного мной приложения заключается в том, что для него требуется файл Excel, содержащий имена, номера лицензий и Тип поставщика медицинских услуг в Орегоне (врач, медсестра, оптометрист и т. папка, выбранная пользователем.
Боковое примечание: Если вы хотите узнать, как написать приложение для парсинга веб-страниц с помощью Puppeteer, я рекомендую вам прочитать эту статью Брэндона Морелли: https://codeburst.io/a-guide-to-automating -scraping-the-web-with-javascript-chrome-puppeteer-node-js-b18efb9e9921 (это также хороший способ освежить в памяти синтаксис async / await в ES8).
Работая над своей программой, я часто запускал приложение Electron из командной строки, чтобы протестировать его, и не сталкивался с проблемами, которые я не мог бы идентифицировать и исправить. Когда я подумал, что закончил, и все выглядело, как задумано, я использовал electronic-packager, чтобы упаковать приложение в исполняемый файл, который можно было распространить среди своей команды. Однако после упаковки приложения и использования значка на рабочем столе для запуска вновь созданного исполняемого файла я столкнулся с серьезной проблемой: моя программа больше не работала.
Приложение запустилось так, как должно было, и выглядело так, как должно было, но когда я нажал кнопку, чтобы начать парсинг, ничего не произошло. Надеясь диагностировать проблему, я запустил исполняемый файл из командной строки. Когда я снова попытался запустить парсинг, я увидел журнал ошибок, в котором сообщалось, что приложению не удалось найти и запустить Chromium. Ой-ой.
Я обратился в Google за ответом и обнаружил, что кроме нескольких веток GitHub, в Интернете не так много информации о включении Puppeteer в приложения Electron. Просматривая эти потоки, я увидел, что у других была такая же проблема, и несколько комментаторов предположили, что вы можете решить эту проблему при вызове puppeteer.launch (), указав параметр «executablePath» непосредственно на расположение Chromium на машине конечного пользователя. Поскольку все в моей команде работают под управлением Windows 10 и уже установили Chrome, я решил, что просто укажу на Chrome, а не на Chromium, поскольку он должен находиться в одном месте на всех компьютерах: C: \ Program Файлы (x86) \ Google \ Chrome \ Application \ chrome.exe
Я сделал это очень легко, создав переменную, хранящую путь к Chrome, и установив эту переменную как исполняемый путь по умолчанию для puppeteer.launch ()
let exPath=‘C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe’ const browser = await puppeteer.launch({executablePath: exPath});
Это решение отлично работало на моем ПК, но что, если конечный пользователь не сохранил Chrome в этом месте? Чтобы решить эту проблему, я добавил новое окно с полем ввода, которое позволяет пользователю выбрать расположение Chrome в файловой системе своего ПК и использовать его в качестве исполняемого пути:
Чтобы получить доступ к файловой системе во всплывающем окне и затем отправить выбранный путь основному процессу, я использовал следующий код в скрипте окна:
const fs = require(‘fs’); const electron = require(‘electron’); const {remote, ipcRenderer} = electron; const dialog = remote.dialog; let fileName; document.getElementById('selectFile').addEventListener('click', openFile); //Runs when select location button is clicked. function openFile(){ dialog.showOpenDialog(function (fileNames) { if (fileNames === undefined) return; fileName = fileNames[0]; fs.readFile(fileName, 'utf-8', function (err, data) { document.getElementById("fileValue").value = fileName; ipcRenderer.send('pathUpdate', fileName); }); }); }
И включил следующий код в основной процесс для обновления пути:
//Updates path to Chrome app on user's machine function chromePathUpdate(newPath){ exPath=newPath; } //Catch pathUpdate ipcMain.on('pathUpdate', (e, newPath) => { chromePathUpdate(newPath); });
После внесения этих обновлений все заработало как шарм, и теперь у меня есть функциональное настольное приложение для очистки веб-страниц.