- Регистрация
- 27.11.2023
- Сообщения
- 96
- Благодарностей
- 181
- Баллы
- 33
Всем привет господа автоматизаторы
,
и дамы коненечно
, если таковые читают эту статью
Сидел я как-то значит и починял свойпримус шаблон с твиттером который внезапно перестал логиниться через креденшиалы. И так попробовал и по другому, и с одним уровнем эмуляции и с другим и браузеры поменял и даже через js навайбкодил дополнительной эмуляции — не логинится и всё. В Zennoposter не логинится, а в ZennoBrowser логинится — никаких проблем. Ладно, думаю, вот и момент, когда переход стал необходим. Прокрастинацию на отдых — шаблоны на адаптацию. Внедрил работу с ZB себе на ферму и... получил от твиттера то же самое шило в то же самое место. Выпытывание причин у Grok, Claude, Gemini и пачки других LLM помогло детерминировать момент когда API возвращает мне бибу, но так и не дало понимания о причинах. Разница была лишь в механизме запуска — профиль ZB запущенный через PM или ZennoPoster не логинится (даже если всё делать ручками), профиль из UI ZB — логинится. Вот только запуская ZB из UI не автоматизируешь ничего — не руками же мне профили греть.
Очевидно нужно было найти способ запуска и автоматизации в обход. Так я узнал, что ZB по API выдаёт строку для подключения к CDP — класс, вот только для того чтобы управлять браузером таким образом нужна какая-то другая библиотека, а у этой библиотеки свои методы, свои зависимости и свои принципы работы. И что более существенно — свой подход к написанию.
Написанное в ZennoPoster остаётся в ZennoPoster?
Я попробовал наваять что-то в Playwright и мне это показалось много трудозатратнее чем в PM — селекторы подбирать неудобно, писать всё сразу тоже, юзер экспириенс по написанию хуже чем в ZP. Вследствие чего переделывать то что уже существует и переучиваться кажется подобным стрельбе по собственным коленям.
Значит надо сделать хотя бы так, чтобы оно работало так как мне удобно и привычно — так я добавил несколько обёрток для методов Playwright и понял что выглядят они ровно так же как те, что и у меня в Zenno, и сигнатуры у них такие же, и логика в общем-то та же. Тут само собой напрашивается — почему не скопировать код из своих шаблонов и не запустить его в среде с этими методами? Я попробовал и сходу у меня конечно ничего не вышло. Пользовался-то я, при написании, куда большим количеством стандартных методов чем просто клики.
Очевидное решение — продолжать. Продолжать реализовывать сущности библиотек Zenno пока скрипт не заведётся. С точки зрения человека задача не очень рентабельная — но нам-то с такой точки зрения смотреть вовсе не с руки. Тут на помощь приходит Клод.
Чтобы дать ему меньше пространства для воображения и побольше данных — через рефлексию я спарсил сигнатуры всех методов и перегрузок + подкинул XML-доки из папки ZennoPoster. Меня порой забавляет как он проводит оценку — получает задачу, думает и пишет "реализация такого займёт примерно неделю"...
после чего получает подтверждение и пишет решение минут 3-5 
В итоге ZP-скрипт копируется в .csx файл — и запускается напрямую, с теми же переменными project, instance и браузерным API что он ожидает в ZP. Прослойка реализует тот же интерфейс. Скрипт работает не подозревая что он уже не в ZennoPoster.
Пример импорта кошелька с PW
, и дамы коненечно
, если таковые читают эту статьюСидел я как-то значит и починял свой
Очевидно нужно было найти способ запуска и автоматизации в обход. Так я узнал, что ZB по API выдаёт строку для подключения к CDP — класс, вот только для того чтобы управлять браузером таким образом нужна какая-то другая библиотека, а у этой библиотеки свои методы, свои зависимости и свои принципы работы. И что более существенно — свой подход к написанию.
Написанное в ZennoPoster остаётся в ZennoPoster?
Я попробовал наваять что-то в Playwright и мне это показалось много трудозатратнее чем в PM — селекторы подбирать неудобно, писать всё сразу тоже, юзер экспириенс по написанию хуже чем в ZP. Вследствие чего переделывать то что уже существует и переучиваться кажется подобным стрельбе по собственным коленям.
Значит надо сделать хотя бы так, чтобы оно работало так как мне удобно и привычно — так я добавил несколько обёрток для методов Playwright и понял что выглядят они ровно так же как те, что и у меня в Zenno, и сигнатуры у них такие же, и логика в общем-то та же. Тут само собой напрашивается — почему не скопировать код из своих шаблонов и не запустить его в среде с этими методами? Я попробовал и сходу у меня конечно ничего не вышло. Пользовался-то я, при написании, куда большим количеством стандартных методов чем просто клики.
Очевидное решение — продолжать. Продолжать реализовывать сущности библиотек Zenno пока скрипт не заведётся. С точки зрения человека задача не очень рентабельная — но нам-то с такой точки зрения смотреть вовсе не с руки. Тут на помощь приходит Клод.
Чтобы дать ему меньше пространства для воображения и побольше данных — через рефлексию я спарсил сигнатуры всех методов и перегрузок + подкинул XML-доки из папки ZennoPoster. Меня порой забавляет как он проводит оценку — получает задачу, думает и пишет "реализация такого займёт примерно неделю"...
после чего получает подтверждение и пишет решение минут 3-5 
В итоге ZP-скрипт копируется в .csx файл — и запускается напрямую, с теми же переменными project, instance и браузерным API что он ожидает в ZP. Прослойка реализует тот же интерфейс. Скрипт работает не подозревая что он уже не в ZennoPoster.
Пример импорта кошелька с PW
C#:
// RabbyWallet.csx
// executor: csx-internal
string HeClick((string tag, string attribute, string value, string typeOfSearch, int index) he, int maxRetries = 30)
{
while (instance.ActiveTab.FindElementByAttribute(he.tag, he.attribute, he.value, he.typeOfSearch, he.index).IsVoid && maxRetries > 0)
{
maxRetries--;
Thread.Sleep(1000);
}
if (instance.ActiveTab.FindElementByAttribute(he.tag, he.attribute, he.value, he.typeOfSearch, he.index).IsVoid)
throw new Exception($"no btn by parameters ({he.tag}, {he.attribute}, {he.value}, {he.typeOfSearch}, {he.index})");
instance.ActiveTab.FindElementByAttribute(he.tag, he.attribute, he.value, he.typeOfSearch, he.index).RiseEvent("click", "Full");
return $"[CLICK SUCCESS] ({he.tag}, {he.attribute}, {he.value}, {he.typeOfSearch}, {he.index})";
}
void ImportRabbyWallet(string filePath)
{
//instance.InstallCrxExtension(filePath); // no-op — расширение уже в профиле для ZB
var tab = instance.NewTab("1");
Thread.Sleep(5000);
instance.ActiveTab.Navigate("chrome-extension://acmacodkjbdgmoleebolmdjonilkdbch/index.html#/new-user/guide", "");
HeClick(("button", "innertext", "I\\ already\\ have\\ an\\ address", "regexp", 0));
HeClick(("img", "src", "aa199324eab773e560e1e3cc56a2a841.svg", "regexp", 0));
var inputs = instance.ActiveTab.FindElementsByAttribute("input:password", "fulltagname", "input:password", "regexp");
var seed = "few produce rose excuse three wage harvest stadium balance useful acoustic uncover";//project.Variables["seed"].Value;
var seedParts = seed.Split(' ');
for (int i = 0; i < 12; i++)
inputs[i].SetValue(seedParts[i], "Full", false);
Thread.Sleep(2000);
HeClick(("button", "innertext", "Confirm", "regexp", 0));
Thread.Sleep(2000);
instance.UseFullMouseEmulation = true;
instance.ActiveTab.FindElementById("password").SetValue("test_password", "Full", false);
instance.ActiveTab.FindElementById("confirmPassword").SetValue("test_password", "Full", false);
instance.UseFullMouseEmulation = false;
HeClick(("button", "innertext", "Confirm", "regexp", 0));
HeClick(("button", "innertext", "Get\\ Started", "regexp", 0));
HeClick(("button", "innertext", "Done", "regexp", 0));
}
try{
ImportRabbyWallet(@"W:\work_hard\zenoposter\CURRENT_JOBS\.crx\Rabby-Wallet-Chrome-Web-Store.crx");
}
catch (Exception ex)
{
log.Warn($"[FULL ERROR] {ex}");
throw;
}
Последнее редактирование:



)
...
.
?) - нет просто неккорректная обработка упавшой задачи). Эти записи копятся и занимают слоты. В API к счастью есть метод для очистки - нам осталось лишь прикрутить нужные кнопки к интерфейсу.
\

