Как стать автором
Обновить

Скрипт проверки баланса Мегафон

Время на прочтение 5 мин
Количество просмотров 20K
Доброго времени суток.

В очередной раз столкнулся с проблемой проверки баланса моих многочисленных симок Мегафона для мобильного интернета — автомобиль, дача, 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.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0"

balance=""
i=0
attempts=5
timeout=20

username='phone_number' # 10-ти значный номер телефона без 8-ки и 7-ки
password='password' # пароль от ЛК

while [[ "$balance" == "" && "$i" -le "$attempts" ]]; do
let "i+=1"
# ---------- CSRF / SessionID ---------------
CSRF=`curl -A "$useragent" -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 -A "$useragent" -b "$cookies" -dump -L -X POST "$login_url" -d "$userdata" | grep -E -o "Баланс\s\S+\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. Логин и пароль лучше вынести в параметры передаваемые скрипту, чтобы был более универсальным.

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

Как-то так.

Идеи и критика приветствуются.

З.Ы. Для частных клиентов, всеж лучше и проще отпарсить страничку ИК (Интернет Кабинет) вместо ЛК.
На ИК пускает без залогинивания, достаточно перейти на страничку user.megafonmoscow.ru через симку меги.
И отпарсить там можно сразу и баланс и остаток траффика, что тоже очень актуально.
Сегодня наваяю новый скриптик.

Вторая версия скрипта проверки баланса.
Будет работать только на тарифах для частников. Проверка баланса и остатка траффика осуществляется той сим карты с которой скрипт ходит в инет. Скрипт шлет сообщение на мыло в случае достижения определенной суммы на балансе или определенного остатка траффика.

#!/bin/bash
page_dump=/usr/tmp/dump
url='http://user.moscow.megafon.ru/'
useragent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0"
balance=""
traffic=""
phone=""
balance_deadline="100"
traffic_deadline="1"

# -------- sendmail function -------------
function sendalert () {
FROM_EMAIL_ADDRESS="my@mail.ru"
EMAIL_USER="userlogin"
EMAIL_ACCOUNT_PASSWORD="password"
TO_EMAIL_ADDRESS="mailto@domain.ru"

echo "$2" | mailx -s "$1" \
-S smtp-use-starttls \
-S ssl-verify=ignore \
-S smtp-auth=login \
-S smtp=smtp://smtp.yandex.ru \
-S smtp-auth-user="$EMAIL_USER" \
-S smtp-auth-password="$EMAIL_ACCOUNT_PASSWORD" \
-S from="$FROM_EMAIL_ADDRESS" \
"$TO_EMAIL_ADDRESS"
}

curl -A "$useragent" -dump "$url" >"$page_dump"
balance=`cat "$page_dump" | grep -E -o 'balance(\S+\s)*' | grep -E -o '[0-9]{1,},[0-9]{1,}'`
traffic=`cat "$page_dump" | grep -E -o 'traffic-by\S+' | grep -E -o '[0-9]{1,}(,[0-9]{1,})*'`
phone=`cat "$page_dump" | grep -E -o 'phone.*+7' | grep -E -o '\([0-9]{3}\)\s[0-9]{3}(-[0-9]{2}){2}'`

bal_test=`echo "$balance" | sed -e 's/,.*//'`
traff_test=`echo "$traffic" | sed -e 's/,.*//'`

if [ "$traff_test" -lt "$traffic_deadline" ]; then
   sendalert "Траффик ниже допустимого $phone" "Номер телефона - $phone
Остаток траффика - $traffic ГБ" 
fi

if [ "$bal_test" -lt "$balance_deadline" ]; then
   sendalert "Баланс ниже допустимого $phone" "Номер телефона - $phone
Ваш баланс - $balance руб." 
fi

if [ -f "$page_dump" ]; then 
   rm "$page_dump"
fi

exit 0


Второй вариант функции отправки письма
Не знаю какой лучше. Работает и так и так вполне стабильно.

# -------- sendmail function -------------
function sendalert () {
FROM_EMAIL_ADDRESS="my@mail.ru"
EMAIL_USER="userlogin"
SMTP_SERVER="smtp.yandex.ru"
EMAIL_ACCOUNT_PASSWORD="password"
TO_EMAIL_ADDRESS="mailto@domain.ru"

sendEmail -f "$FROM_EMAIL_ADDRESS" \
          -t "$TO_EMAIL_ADDRESS" \
          -s "$SMTP_SERVER" \
          -o message-charset=utf8 \
          -xu "$EMAIL_USER" \
          -xp "$EMAIL_ACCOUNT_PASSWORD" \
          -u "$1" \
          -m "$2"
}


Функцию отправки мыла реализовал двумя способами — mailx и с помощью перлового скрипта sendEmail. Для последнего могут потребуются дополнительные пакеты — Perl-Net-SMTP-SSL, Perl-Net-SSLeay, Perl-IO-Socket-SSL, Perl-Crypt-SSLeay.
Вышеуказанные скрипты отправки почты проверял на smtp.yandex.ru!!! На других серваках возможно необходимо будет подкрутить настройки.

З.З.Ы.
mailx работает быстрее…
Теги:
Хабы:
+4
Комментарии 31
Комментарии Комментарии 31

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн