-
Notifications
You must be signed in to change notification settings - Fork 7
Для авторов новых плагинов
Инструкция написана чтобы на старте ответить на основные вопросы.
Т.к. пока желающих писать собственные плагины не сказать что очень много мне в большинстве случаев на вопросы по написанию плагинов проще ответить лично, чем заниматься написанием серьезной инструкции. По тем же причинам я пока не обдумывал серьезно как быть если плагинов и авторов будет слишком много и нужно будет это как-то аккуратно разрешать от конфликтов. Появиться такая проблема - будем думать.
Пока конфликты решаю вручную, изменения и новые плагины принимаются в виде pull request от авторов в ветку dev
Если же Вы хотите сделать плагин, но категорически не хотите разбираться с гитом (что на мой взгляд зря) - то это менее желательный вариант, но присылайте тогда в личку добавлю самостоятельно.
Плагины - это программа на питоне - файл, расположенный в папке mbplugin/plugin, содержащий функцию:
def get_balance(login, password, storename=None, **kwargs):
result = {'Balance': 124.45}
return result
Пример простого плагина и возвращаемые параметры можно посмотреть в файле mbplugin/plugin/test1.py
Если Вы хотите получить какие-то данные с веб страницы и вариант просто воспользоваться библиотеками типа request, примеры такого использования можно найти например в плагинах megafon или avtodor-tr
Если Вы хотите получить какие-то данные с веб страницы и вариант просто воспользоваться библиотеками типа request Вам по каким-то причинам не подходят, то можно воспользоваться playwright. В принципе никто не мешает пользоваться им напрямую, но я реализовал основную часть рутины в классе BrowserController
, для упрощения использования на типичных сайтах, что позволяет в большинстве случаев написать плагин буквально за 10 строчек кода.
Пример такого плагина смотрите в mbplugin/plugin/test1.py
Собственно все плагины являются примерами и вполне можно в коде посмотеть как что реализовано и утянуть идеи в свой плагин. Только советую не начинать изучение с плагинов МТС и Теле2 они получились довольно навороченными в силу ряда особенностей и на старте понять как что там сделано будет трудно.
Т.к. в основном все страницы в окне логона довольно похожи, то для того чтобы понять куда писать логин и пароль хватит универсальных тэгов.
Они описаны в структуре default_logon_selectors в файле mbplugin/plugin/browsercontroller.py
Все уточнения проводим открыв окно логона в браузере и запустив отладчик.
Если какие-либо из них не подходят (самые распространенные причины - поле логина не находится по type=text или кнопка submit как то замысловато обнаруживается) - то создаем словарь user_selectors с теми значениями, которые должны перекрыть значения по умолчанию.
Для логона используем do_logon передавая в user_selectors изменения значений по умолчанию
self.do_logon(url=login_url, user_selectors=user_selectors)
В большинстве случаев интересующая информация приходит в json сразу после нажатия submit, так что в простом случае просто пытаемся после логона получить из приходящих json данные с помощью вызова метода
self.wait_params(params=[{
'name': 'Balance', 'url_tag': ['object/meters'], 'jsformula': "data.data.sensors[0].meters.length",
}])
В self.wait_params можно указать несколько параметров в одном вызове.
Подробное описание смотрите так же в файле mbplugin/plugin/browsercontroller.py
В данном примере мы получаем значение параметра Balance со страницы url или POST запрос которой содержит 'object/meters' для получения берем содержимое json ответа как переменную data и выполняем data.data.sensors[0].meters.length
.
Для отладки удобно в консоли браузера присваивать переменной data полученный json и дальше прямо в отладчике пытаться написать выражение, дающее требуемый результат.
Если же обработку полученного json необходимо провести на python то вместо jsformula пишем код на python в параметре pformula
В случае если данные необходимо просто получить со страницы указываем пустой url_tag и просто пишем выражение для анализа данных со страницы, отладить его можно точно также в отладчике.
Несмотря на то, что можно к экземпляру playwright page можно обратиться через self.page
для наиболее часто используемых действий сделаны специальные обертки исключающие необходимость обработки ошибок:
self.page_click
- (обертка для page.click) кликнуть на элемент
self.page_content
- (обертка для page.content) полное содержимое страницы в html
self.page_evaluate
- (обертка для page.page_evaluate) выполнение js кода в браузере
self.page_fill
- (обертка для page.fill) заполнить в поле
self.page_goto
- (обертка для page.goto) переход по url
self.page_press
- (обертка для page.press) симуляция нажатия на клавиатуру
self.page_reload
- (обертка для page.reload) перезагрузить страницу
self.page_screenshot
- (обертка для page.screenshot) сохранение скриншота со страницы в папку с логами (очень помогает при отладке, не не увлекайтесь - скриншоты занимают место)
self.page_type
- (обертка для page.type) ввести текст в поле
self.page_wait_for
- (обертка сразу для комбинации методов page.wait_for_load_state, page.wait_for_url, page.wait_for_selector) ожидание события на странице, при использовании wait_for_load_state и wait_for_selector учитывайте что оно не всегда дает ожидаемый результат, поэтому я добавил вариант expression - ожидание что js выражение вернет true
self.sleep
- (обертка для page.wait_for_timeout) правильный sleep (внимание! хоть playwrith и синхронное приложение, под капотом у него асинхронные вызовы, так что использовать time.sleep
крайне не рекомендуется, используйте вместо него self.sleep
)
Также при желании можно использовать все остальные возможности playwright обращаясь напрямую через self.page
, но тогда не забудьте про обработку ошибок.
В любом случае можно посмотреть плагины других провайдеров и скорее всего найдутся похожие на Ваш случаи.
В ходе разработки естественно возникают ошибки, для того чтобы понять что идет не так я запускаю проверку командой
mbp check-plugin p_pluginname login password
И затем смотрю в файле mbplugin/log/mbplugin.log ошибки. (еще удобнее через tail -f
)
Также в таком варианте запуска можно воспользоваться и breakpoint()
, главое не забудьте их убрать перед реальным использованием.
Для полноты картины иконку, которая будет видна в MobileBalance, можно сделать с помощью утилиты mbplugin/plugin/get_icon.py указав ей либо url либо скачанный файл favicon.ico или его аналог. иконка - это переменная icon в теле модуля.