Как-то раз я разрабатывал инфраструктуру под запуск большого количества ботов. В качестве языка программирования я выбрал так мною любимый Node.JS.Для начала я создал простое приложение, которое умело запускать браузер Firefox, закрывать и перезапускать его, а уже в нем через iMacros выполнялись различные действия.
Упрощенная логика примерно такая:
var spawn = require('child_process').execFile; var child = spawn('C:/ff35/App/Firefox/firefox.exe'); child.kill(); //process.kill(child.pid, 'SIGHUP'); // SIGTERM, SIGINT, .... is not working for me
Суть в том, что я завершал процесс при помощи команды process.kil(pid, signal)
, где pid
— это идентификатор процесса, который можно посмотреть в диспетчере задач, а signal
— это тип посылаемого сигнала. Я пробывал все возможные сигналы, надеясь добиться корректного выключения firefox, но ничего не вышло. Хочу заметить, что действие команды process.kill()
аналогично тому, как если просто убить процесс через диспетчер задач. В обоих случаях, это называется «аварийное завершение» процесса. Начинающие пользователи Selenium тоже часто сталкиваются с подобными проблемами. При возникновении такой ситуации вылезает вот такое окошко или нечто похожее на него(зависит от версии браузера).
В итоге, при попытке программно перезапустить(остановить+запустить) процесс, очень часто вылезало такое окно и бот не мог выполнять никакие действия в браузере. Это было очень плохо, я пару дней зависал на stackoverflow и в гугле, перепробывал много разных способов, но ничего не помогало, к тому же в зависимости от версии браузера, способы могли работать или не работать.
В-общем, нашлось универсальное решение для всех версий FireFox выше 23, что меня вполне устраивало. Всего-то, нужно добавить две переменные окружения.
MOZ_DISABLE_SAFE_MODE_KEY = 1;
MOZ_DISABLE_AUTO_SAFE_MODE = 1;
Для тех, кто не в курсе, что это такое — кликните: Мой компьютер -> Свойства - > Переменные среды
, там будет окошко Системные переменные
.Я сделал проще, прямо в коде указал, что при запуске нужно использовать такие enviroment variables. Вот что в итоге получилось.
var spawn = require('child_process').execFile; var environment = process.env; environment.MOZ_DISABLE_SAFE_MODE_KEY = 1; environment.MOZ_DISABLE_AUTO_SAFE_MODE = 1; var config = { env: environment }; var child = spawn('C:/ff35/App/Firefox/firefox.exe', [], config); child.kill();
Теперь все работает идеально, я могу полноценно контролировать запуск и убийство всех процессов, хоть каждую секунду, без сбоев и геморроев и мои боты работают слаженно и непрерывно. Без решения этой задачи, нормально контролировать своих ботов было бы невозможно и пришлось бы ручками закрывать подвисшие браузеры и таблички safe mode.
Пишите в комментарии, если помогло или если есть вопросы.
как Node.js определяет, что процесс подвис?
или перезапуск происходит с определенной частотой?
Все довольно просто: каждый бот соединен с локальным управляющим сервером при помощи WebSocket и в режиме реального времени можно его мониторить. Я использую Socket.IO — там встроенная поддержка «серцебиения» — то есть через небольшие промежутки времени идет проверка, если отсутствует серцебиение или сработало событие «ondisconnect» или если в течении минуты нет проверочного сигнала, локальный сервер автоматически перезапускает браузер.
немного не понято как это работает было бы интересно узнать подробности
Три дня повтыкаф научил бота соединяться с сервером и отправлять туда сообщения. Как же сделать условия что если сервер не принял в течении какого то времени сообщения от бота то выполнял закрытия сокета или любое другое действие, но если сообщение пришло то ничего не делал бы и обнулял время ожидания
Спасибо автору большое! Два года мучился с этой проблемой и нигде не мог найти решения как устранить эту проблему