Доброго времени суток.
В очередной раз столкнулся с проблемой проверки баланса моих многочисленных симок Мегафона для мобильного интернета — автомобиль, дача, iPad, мобильный роутер и.т.д. Проблема в том, что данные симки работают в модемах и иных гаджетах и могут быть не всегда под рукой. Более того, времени и желания постоянно мониторить состояние баланса в разных устройствах, в том числе и удаленных, просто нет. А интернет имеет обыкновенно «заканчиваться» в самый неподходящий момент.
На сегодняшний день у ОПСОСов существуют следующие варианты проверки баланса:
1. Отправка смс на короткий номер
2. Личный интернет-кабинет
3. USSD команда
4. Звонок на короткий номер
Не понимаю, что мешает операторам добавить в личный кабинет модуль — оповещение по электронной почте абонента при достижении порога баланса в ххх рублей.
Собственно это я и собираюсь реализовать с помощью bash скрипта.
Пойду я «тупиковым» путем — парсинг странички личного кабинета. Тупиковым, потому что ОПСОсы постоянно что-то меняют в коде страничек и в скором времени скрипт перестанет работать, как перестал работать например вот этот. В ближайшем будущем планирую сделать скрипт на основе USSD или путем отправки SMS, правда в таких случаях необходимо подключение модема в комп или роутер (например mikrotik), в котором есть возможность создания скриптов.
Вот готовый скрипт парсинга странички личного кабинета.
Вкратце механизм:
1. Сохранение курлом ID сессии и печеньки (при заходе на страничку ЛК неким скриптом генерится ID и привязывается к текущей сессии, по этому в один заход курлом не залогиниться).
2. Залогинивание в ЛК с использованием сохраненной куки и session ID.
3. Парсинг странички и выцепление баланса.
#!/bin/bash
cookies=./cookies.txt
sessionID_url='https://lk.megafon.ru/login/'
login_url='https://lk.megafon.ru/login/dologin/'
logout_url='https://lk.megafon.ru/logout/'
# useragent='Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0'
balance=""
i=0
attempts=5
timeout=20
username='phone_number' # 10-ти значный номер телефона без 8-ки и 7-ки
password='password' # пароль от ЛК
while [[ "$balance" == "" && "$i" < "$attempts" ]]; do
let "i+=1"
echo "$i"
# ---------- CSRF / SessionID ---------------
CSRF=`curl -c "$cookies" "$sessionID_url" | grep "CSRF_PARAM" | grep -o -E "([Aa]|[0-9])S+-S+-S+-S+-S+([Aa]|[0-9])"`
userdata="CSRF=$CSRF&j_username=$username&j_password=$password"
balance=`curl -b "$cookies" -dump -L -X POST "$login_url" -d "$userdata" | grep -E -o "БалансsS+s[0-9]{1,},[0-9]{1,}" | grep -E -o "[0-9]{1,},[0-9]{1,}"`
if [ "$balance" == "" ]; then
sleep "$timeout"
fi
done
if [ "$balance" != "" ]; then
echo "Баланс = $balance руб."
else
echo "Не удалось проверить баланс, повторите попытку позже."
fi
# ------ LOGOUT ---------------------------------
sleep 5
curl -b "$cookies" -L "$logout_url" > /dev/null 2>&1
if [ -f "$cookies" ]; then
rm "$cookies"
fi
exit 0
Какие есть «косяки»:
1. Иногда сервак меги выплевывает «сервис временно недоступен», по этому сделал несколько попыток получения баланса с таймаутом.
2. При ошибках залогинивания (неправильный пароль или номер телефона) — может выскочить каптча и тогда скрипт не будет работать до тех пор пока не залогинитесь через вэб с вводом каптчи.
3. Не нравится парсинг в два прохода grep'ом. Знаю, что можно sed'ом в один проход, но что то пока не выходит.
4. Лучше сначала сохранять целиком код страницы во временный файл, а потом уже парсить (как здесь) — так можно будет отпарсить различные ошибки залогинивания или сервиса.
5. Логин и пароль лучше вынести в параметры передаваемые скрипту, чтобы был более универсальным.
Далее буду делать небольшой управляющий скрипт (в процессе создания), который будет вызывать вышеуказанный с различными логинами и паролями и проверять не упал ли баланс ниже заданного порога с отправкой уведомлений по мылу.
Далее запихну его в крон например на вэб серваке с запуском один раз в день.
Как-то так.
Идеи и критика приветствуются.
Автор: Bearpuh