ARMANOS

Сборщик сценариев

Автоматизация без кода

Соберите сценарий из шагов и запустите его сразу на многих профилях. Каждый шаг выполняется внутри браузера профиля, с его отпечатком, куками и прокси.
16
Видов шагов
4 уровня
Глубина вложенности
до 8 за прогон
Профилей одновременно
100 на профиль за прогон
Снимков экрана

Сценарий это упорядоченный список шагов

У сценария есть имя, список шагов по порядку, свои переменные, выбранные профили и число профилей, которые идут одновременно. Всё это принадлежит самому сценарию. Переключившись на другой сценарий, вы не унесёте туда чужой выбор профилей, а сам выбор переживает перезапуск программы.

Сценарии лежат на вашем компьютере, в файле rpa-flows.json внутри папки данных программы. Файл пишется правами только для хозяина: в шагах часто стоит логин или значение формы. Каждое сохранение проходит чистку, которая оставляет известные поля и выбрасывает остальные, чтобы исполнитель мог доверять тому, что читает обратно.

Пределы поставлены нарочно: 200 сценариев в файле, 500 шагов в одном списке и не больше 4 уровней вложенности. Они нужны, чтобы правленный руками или привезённый файл не заставил программу считать бесконечно.

Сегодня есть шестнадцать видов шагов. Десять простые. Шесть посложнее: ветвление, обход списка, вкладки, куки, свой JavaScript и ожидание сетевого запроса.

ШагЧто делаетЧто нужно
Перейти по URLОткрывает адрес в текущей вкладкеАдрес http или https, либо переменная, которая в него разворачивается
ОжиданиеЖдёт заданное время или появления элементаМиллисекунды либо селектор CSS и предел ожидания
КликПодводит элемент к середине экрана и нажимает его центрСелектор CSS
Ввод текстаСтавит курсор в поле, очищает его и набирает значениеСелектор и значение
ПрокруткаПрокручивает на столько-то точек или до элементаВеличина либо селектор
Извлечь текстКладёт текст элемента в переменнуюСелектор и имя переменной
Сделать скриншотСохраняет снимок страницы в PNGНичего
Нажать клавишуПосылает странице одно нажатиеИмя клавиши, по умолчанию Enter
Случайная задержкаЖдёт случайное время между двумя границамиДве величины в миллисекундах
ПовторВыполняет своё тело заданное число разОт 1 до 1000 проходов
Если / иначеПроверяет страницу или переменную и идёт по одной из двух ветокОдна из пяти проверок
Для каждого элементаВыполняет тело по разу на каждый найденный элементСелектор, потолок, переменная
Управление вкладкамиОткрывает, переключает или закрывает вкладку того же профиляАдрес, номер или кусок адреса
КукиЧитает, пишет, удаляет и чистит куки в сессии этого профиляИмя и открытая страница либо домен
Выполнить JavaScriptВыполняет ваш код в странице и сохраняет результатКод, до 20000 знаков
Ждать запросЖдёт, пока страница сделает запрос с нужным куском в адресеКусок адреса и предел ожидания
Сборщик сценариев: слева список сценариев, в середине шаги с отступом внутри повтора, ниже переменные, выбранные профили и журнал прогона.
Один экран: сценарии, шаги, переменные, выбранные профили и живой журнал прогона.

Сценарий собирается руками, а сборщик называет поломки

Записи действий нет. Программа не следит за вашими нажатиями и не превращает их в шаги. Каждый шаг добавляется через форму: выбрать вид, заполнить нужные поля, сохранить. Шаги двигаются вверх и вниз двумя кнопками, а перед удалением ветки или цикла программа говорит, сколько вложенных шагов уйдёт вместе с ним.

Взамен сборщик проверяет сценарий прямо во время правки. Он ищет молчаливые поломки, те, что вылезают посреди прогона на живом аккаунте: клик без цели, ожидание без времени и без элемента, извлечение без переменной, шаг вкладки без адреса, свой код без кода.

Каждое замечание говорит, о каком по счёту шаге речь. Ошибки отделены от предупреждений, а сам список стоит прямо под шагами.

Проверка ничего не запрещает. Незаконченный сценарий это нормальная рабочая ситуация: вы вернётесь к нему завтра, а запрет сохранять означал бы просто потерянную работу.

Как сценарий уезжает с этого компьютера

Выгрузка кладёт сценарий в один файл JSON и нарочно не берёт с собой то, что набрано руками: значения полей ввода, значения кук и значения переменных. Именно там лежат входы. Имена переменных остаются, чтобы получатель видел, что заполнить, и ссылки {{переменная}} тоже остаются, иначе сценарий у него не соберётся. Ввоз всегда создаёт новый сценарий и никогда не затирает существующий, а сколько шагов выбросила чистка, он говорит числом, а не молчанием. Чтобы перевезти сценарий на свою вторую машину вместе со значениями, есть общая библиотека в аккаунте.

Переменные подставляют своё значение каждому профилю

В любое текстовое поле шага можно вписать {{имя}}. При запуске оно заменяется значением из карты переменных, а неизвестное имя становится пустой строкой, а не ошибкой.

Карта строится один раз на профиль и в три слоя: значения по умолчанию у сценария, затем встроенные поля профиля, затем ваши правки в таблице под выбранными профилями. Так один сценарий входит в двадцать аккаунтов, а не двадцать копий сценария.

Имя переменной можно писать на любом письме. Программа продаётся на 22 языках, и имя «город», 都市 или مدينة переживает сохранение и подставляется при запуске. Чинить пришлось сразу в двух местах: имя, которое сохраняется, но не подставляется, делает сценарий на вид рабочим и молча пустым.

Чтение тоже наполняет переменные. Извлечение текста, чтение куки и шаг со своим кодом кладут результат в названную вами переменную, до 4000 знаков. Значение, взятое из переменной, пишется в журнал точками: журнал лежит на диске и виден на экране.

  • profile.name

    Имя профиля, как оно стоит у вас в списке.

  • profile.group

    Группа, к которой профиль относится.

  • profile.totp

    Одноразовый код из секрета самого профиля. Он считается в момент подстановки, а не при старте прогона: код живёт тридцать секунд, а прогон дольше.

Повтор, ветвление и обход списка

Повтор выполняет своё тело заданное число раз, от 1 до 1000. Сам цикл работой не считается, считаются его дети, поэтому ход прогона отражает то, что происходит на самом деле.

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

Обход списка берёт селектор и потолок, по умолчанию десять. Каждый проход помечает текущий элемент в странице признаком с глубиной цикла, поэтому вложенные циклы не затирают друг друга. Внутри тела на этот элемент указывает @item, работает и «@item .title». Список опрашивается заново на каждом проходе: страница может перерисоваться между проходами, и это не сломает обход, а если список стал короче, цикл заканчивается раньше.

Вне обхода @item нарочно превращается в селектор, который не находит ничего. Тихо взять весь документ значило бы, что шаг не на своём месте нажмёт то, чего вы не выбирали. На самом глубоком уровне сборщик перестаёт предлагать шаги с телом, чтобы не собрать то, что чистка при сохранении выбросит.

Один сценарий, много профилей и очередь, которая ждёт

Профили выбираются кнопками под списком шагов, есть «выбрать все» и «снять». Номера удалённых профилей вычищаются при отрисовке, поэтому запуск не окажется включённым на профиль, которого больше нет.

Одновременность бывает 1, 2, 3, 5 или 8. Прогон заводит столько рабочих, но никогда не больше, чем предел одновременно открытых браузеров на вашей машине. Предел считается по памяти: вся память минус 3 ГБ системе и программе, дальше по гигабайту на браузер, снизу 4, сверху 32. Число можно поправить рукой, если вы знаете своё железо.

Упёршись в предел, рабочий не записывает профиль в провал. Он ждёт свободного места, проверяя каждые пять секунд, до получаса, и только потом честно сообщает об отказе. Раньше ночной прогрев тридцати профилей рушился целиком за доли секунды: первый же рабочий помечал профиль проваленным и тут же брал следующий.

Профиль запускается, если ещё не открыт, и шаги идут в его первом окне. Можно уйти на другой сценарий: прогон продолжается, а сверху едет полоска с кнопкой «Стоп». Остановка не рубит с плеча, её проверяют перед каждым шагом на каждом уровне вложенности, поэтому цикл разматывается, а не обрывается посреди действия.

Выбор одновременности
1, 2, 3, 5, 8
Сколько рабочих заводится
не больше предела открытых браузеров
Предел открытых
(память минус 3 ГБ) по гигабайту, снизу 4, сверху 32
Ожидание места
опрос каждые 5 с, до 30 мин
Журнал прогона
хранится 600 строк, в окно уходят последние 400
Законченных прогонов на диске
последние 20

Числа сняты с исполнителя прогона и с расчёта предела по памяти в программе.

Когда шаг не удался

Провал шага не заканчивает прогон. Шаг попадает в журнал с ошибкой, счётчик у этого профиля растёт, и берётся следующий шаг. Сценарий из тридцати шагов покажет, какие именно сломались, а не встанет на первом, спрятав остальные.

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

Итог честный. «Готово» значит «сделано то, что написано». Если у профиля провалился хоть один шаг, профиль помечен провалом и сказано, сколько шагов не вышло. Если провалился хоть один профиль, провален весь прогон, и уведомление красное, а не зелёное. Раньше итог судили только по тому, упал ли сам профиль, и сценарий из трёх шагов, где сломались все три, докладывался как успех.

Число берётся из счётчика рядом с прогоном, а не из журнала: журнал обрезается до последних 600 строк. На длинном прогоне ранние ошибки вытеснялись раньше, чем вы до них дочитаете, и итог снова зеленел ровно там, где прогон долгий и за ним никто не следит.

Законченные прогоны пишутся в rpa-runs.json, последние двадцать. Ночной прогон можно прочитать утром, после перезапуска, а это единственный момент, когда журнал прогона по-настоящему нужен. У шага со своим кодом по той же причине стоит предел в шестьдесят секунд: вечное обещание в коде страницы вешало прогон навсегда, и «Стоп» не помогал.

Снимки экрана и где они оказываются

Шаг со снимком снимает страницу и пишет PNG. На встроенном движке это собственный снимок окна, на ARMANOS Browser это Page.captureScreenshot по каналу отладки. Один шаг, одна дорога в коде, два движка.

Файлы ложатся в папку rpa-screenshots внутри папки данных программы. Папка создаётся правами только для хозяина, и каждый PNG пишется так же. Снимок профиля это открытая сессия: на нём и почта, и переписка, и одноразовый код, если он в этот миг на экране.

Потолок сто снимков на профиль за прогон. Шаг со снимком внутри повтора внутри повтора иначе заполнит диск за ночь. Превышение выходит обычной ошибкой шага «слишком много снимков», то есть видно в журнале, а не по кончившемуся месту на диске.

Кнопка «Открыть папку снимков» стоит в шапке карточки запуска и на пустом экране, чтобы до снимков можно было добраться после перезапуска, когда никакого прогона на экране нет.

Какие области отладки мы нарочно не включаем

ARMANOS Browser это отдельный процесс Chromium, 153.0.7978.0, поэтому сценарий ведёт его по протоколу отладки на петле. Встроенный движок Electron ведётся напрямую через своё окно. Обе дороги завёрнуты в одну форму, поэтому шаг написан один раз, а наш движок для автоматизации полноправен, а не «не поддерживается».

Две области не включаются никогда: Runtime.enable и Page.enable. От их включения Chromium ставит зацепки, которые код страницы способен заметить, и именно их ищут известные приёмы с console.debug и временем разбора Error.stack.

Они и не нужны. Runtime.evaluate, Page.navigate, ввод и сетевые команды работают без включения своей области. Готовность страницы опрашивается через document.readyState, а не подпиской на события жизненного цикла. Network.enable включается только на время шага ожидания запроса, он живёт на стороне браузера и следа, видимого из JavaScript, не оставляет.

При рукопожатии по WebSocket не посылается и заголовок Origin: от него Chromium требует лишний ключ в командной строке, а командная строка видна. У встроенного движка незащищённый порт отладки открывается только тогда, когда работает именно он: иначе через этот порт до окна дотянулась бы любая программа на той же машине под тем же пользователем.

На мобильном профиле шаг клика посылает касание, а не нажатие мыши. Замерено на живом окне: движок превращает нажатия мыши в касания, вызов не возвращается вовсе, и раньше любой сценарий на мобильном профиле вставал на первом же клике и падал по времени.

Что это даёт и чего не даёт

Выключенные области убирают один признак, который страница читает напрямую. О поведении это не говорит ничего. Скорость, порядок, объём и час запуска остаются за вами, и сценарий, который нажимает тридцать одинаковых кнопок за тридцать секунд, так и выглядит.

Запуск по расписанию

Расписание принадлежит сценарию и называет профили, время и сколько профилей идут одновременно, до пяти. Три вида: ежедневно в такое-то время, по выбранным дням недели, каждые N часов.

Время местное. После перевода часов девять утра остаётся девятью утра, а не сползает на восемь.

Пропущенное не догоняется. Компьютер спал три дня, значит три запуска не состоялись, а выполнить их разом это ровно тот всплеск, которого вы избегаете. Число пропусков записывается, чтобы окно могло вам о нём сказать, ничего при этом не запуская. Профиль, открытый прямо сейчас, расписание не трогает.

Расписание работает, только пока открыта программа. Служб в системе мы не ставим, окно говорит об этом прямо, и лучше сказать заранее, чем дать вам узнать об этом в понедельник.

Исход дописывается, когда прогон закончился, а не когда он начался, и хранится знаком: ok, stopped, error:2/5. Слова подбираются при показе, поэтому расписание, уехавшее на машину с другим языком, читается верно. Все расписания видны и одним списком, по ближайшему сроку.

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

  1. 1

    Выберите сценарий

    Нажмите значок часов в его строке в списке сценариев.

  2. 2

    Выберите время

    Ежедневно, по дням недели или каждые N часов, по вашему местному времени.

  3. 3

    Выберите профили

    Отметьте нужные и скажите, сколько идут одновременно, от 1 до 5.

  4. 4

    Оставьте программу открытой

    Расписание срабатывает из работающей программы. Ближайший срок виден в строке сценария.

  5. 5

    Прочитайте исход

    В строке видно последний запуск, его результат и сколько запусков было пропущено.

Чего это не делает

  • Записи действий нет. Никто не следит за вашими нажатиями и не превращает их в шаги. Каждый шаг добавляется руками через форму.
  • Сценарий это сценарий, а не человек. Он повторяет написанное с теми паузами, которые вы задали, ровными или случайными. Страницу он читает не так, как вы, и смена вёрстки на сайте ломает селектор.
  • Ни разгадывания капчи, ни распознавания картинок, ни шага с машинным обучением. Там, где сайт задаёт человеческий вопрос, сценарий останавливается.
  • Расписание работает, только пока открыта программа. Никакой службы в фоне нет, закрытый ноутбук свои запуски пропускает, и пропущенное никогда не выполняется пачкой.
  • Выключенные области отладки убирают один признак. Это не утверждение про распознавание вообще, и никакого обещания, что сайт примет ваш прогон за человека, здесь нет.

Как проверить

Каждое утверждение, файл, который его выполняет, и стенд, который его стережёт.

Шаг перехода принимает только http и https, и адрес проверяется ещё раз при запуске, после подстановки переменных
apps/desktop/src/lib/rpa.js · apps/desktop/test/rpa-reach.js
Сборщик называет поломки до запуска и никогда не запрещает сохранять
apps/desktop/src/lib/flowCheck.js · apps/desktop/test/flow-check.js
«Готово» значит «шаги выполнились»: профиль с провалившимися шагами помечен провалом, а счёт берётся из счётчика, а не из обрезаемого журнала
apps/desktop/src/main/main.js · apps/desktop/test/run-result-honest.js
Прогон, упёршийся в предел открытых браузеров, ждёт места, а не пишет профиль в провал
apps/desktop/src/main/main.js · apps/desktop/test/сценарий-ждёт-места.js
Сценарий действительно идёт на ARMANOS Browser по каналу отладки, и Runtime.enable с Page.enable не зовутся ни разу
apps/desktop/src/lib/cdp.js · apps/desktop/src/lib/forkPage.js · apps/desktop/test/сценарий-живьём.js

Соберите один сценарий и пустите его на десять профилей

Сборщик, журнал прогона и расписание живут в самой программе. Сценарий не покидает ваш компьютер, пока вы сами не выгрузите его в файл или не отправите в свой аккаунт.