Отображение баланса мобильного телефона на рабочем столе

()

Многие пользователи Linux используют системный монитор Conky для отображения различной информации непосредственно на рабочем столе своего компьютера. Обычно отображают свободное место на диске, загрузку процессора, занятую память и прочие системные параметры. Однако Conky позволяет показывать вообще любые данные и далее будет показано как можно добавить информацию о балансе своего мобильного телефона.

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

В распоряжении автора этих строк оказались в общей сложности три SIM-карты разных операторов: Казанского Билайна, НСС-Волга (филиал в републике Татарстан) и Татарстанского филиала МТС. Для всех трёх операторов успешно были написаны скрипты, которые позволили получать баланс из личных кабинетов для последующего отображения в Conky.

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

Первый скрипт предназначен для работы с мобильным оператором Билайн и получает данные из его личного кабинета по адресу uslugi.beeline.ru:

#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;

use LWP::UserAgent;

# Базовые настройки кскрипта
my $server_user = '9600111111';
my $server_pass = 'y0us3cr3tp4ssw0rd';

my $rv = 'Unknown';

# Если что-то пойдёт не так мы сможем сами обработать ошибку
eval {
        # Создаём объект, с которым будем работать дальше
        my $ua = LWP::UserAgent->new(
                        agent => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10',
                );
        # Инициализируем куки
        $ua->cookie_jar( {} );

        # Выполняем первый запрос (страница авторизации)
        my $response = $ua->get('https://uslugi.beeline.ru/');
        # Сохраняем полученные куки
        $ua->cookie_jar->extract_cookies($response);
        # Запоминаем реферер
        $ua->default_header(Referer => 'https://uslugi.beeline.ru/');

        # Второй запрос - авторизация
        $response = $ua->post(
                'https://uslugi.beeline.ru/loginPage.do',
                        {
                                userName => $server_user,
                                password => $server_pass,
                                ecareAction => 'login',
                        }
                );                
        # Снова сохраняем куки
        $ua->cookie_jar->extract_cookies($response);
        # Запоминаем реферер
        $ua->default_header(Referer => 'https://uslugi.beeline.ru/loginPage.do');
        
        # Получаем индексную страницу личного кабинета
        $response = $ua->get('https://uslugi.beeline.ru/navigateMenu.do');
        # И опять сохраняем куки
        $ua->cookie_jar->extract_cookies($response);
        # Переопределяем реферер
        $ua->default_header(Referer => 'https://uslugi.beeline.ru/navigateMenu.do');

        # Получаем содержимое фрейма с информацией о балансе
        $response = $ua->get('https://uslugi.beeline.ru/vip/prepaid/refreshedPrepaidBalance.jsp');

        # Извлекаем данные о балансе
        if ($response->content =~ m{<td class="tabred">\s+(\d+?(?:,\d+?)?)&nbsp;}ism) {
                $rv = $1;
                $rv =~ s/,/./;
        }
};
# Если что-то пошло не так
if (my $error = $@) {
        # Желающие могут дописать обработку ошибок
}
print "$rv\n";

Сохраним скрипт как ~/scripts/balance_beeline.pl. После запуска этот скрипт напечатает на stdout баланс нашего телефона или UNKNOWN в случае какого-то сбоя.

Второй скрипт для получения информации из iSERVE НСС:

#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;

use LWP::UserAgent;

# Базовые настройки кскрипта
my $iserve_user = '9503123456';
my $iserve_pass = 'y0us3cr3tp4ssw0rd';

my $rv = 'Unknown';

# Если что-то пойдёт не так мы сможем сами обработать ошибку
eval {
        # Создаём объект, с которым будем работать дальше
        my $ua = LWP::UserAgent->new(
                        agent => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10',
                );
        # Инициализируем куки
        $ua->cookie_jar( {} );

        # Выполняем первый запрос (страница авторизации)
        my $response = $ua->get('https://iserve.ncc-volga.ru/?path=logon');
        # Сохраняем полученные куки
        $ua->cookie_jar->extract_cookies($response);
        # Запоминаем реферер
        $ua->default_header(Referer => 'https://iserve.ncc-volga.ru/?path=logon');

        # Второй запрос - авторизация
        $response = $ua->post(
                'https://iserve.ncc-volga.ru/?path=iserv',
                        {
                                userv => $iserve_user,
                                passv => $iserve_pass,
                        }
                );                
        # Снова сохраняем куки
        $ua->cookie_jar->extract_cookies($response);
        # Запоминаем реферер
        $ua->default_header(Referer => 'https://iserve.ncc-volga.ru/?path=iserv');

        # Третий запрос - собственно страница с информацией
        $response = $ua->get('https://iserve.ncc-volga.ru/?path=sms');

        # Извлекаем данные о балансе
        if ($response->content =~ m{<input type="hidden" name="balance" id="balance" value="(\d+?(?:\.\d+?)?)">}) {
                $rv = $1;
        }
};
# Если что-то пошло не так
if (my $error = $@) {
        # Желающие могут дописать обработку ошибок
}
print "$rv\n";

Сохраним его как ~/scripts/balance_ncc-volga.pl. Работает он аналогично скрипту для Билайн.

При написании скрипта для парсинга Интернет-помошника МТС возникли некоторые трудности, связанные с достаточно хитрой защитой от парсинга, но оказалось что Мобильная версия Интернет-Помощника такой защиты не содержит и было решено парсить её. Вот готовый скрипт:

#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;

use LWP::UserAgent;

# Базовые настройки кскрипта
my $server_user = '9172345678';
my $server_pass = 'y0us3cr3tp4ssw0rd';

my $rv = 'Unknown';

# Если что-то пойдёт не так мы сможем сами обработать ошибку
eval {
        # Создаём объект, с которым будем работать дальше
        my $ua = LWP::UserAgent->new(
                        agent => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10',
                );
        # Инициализируем куки
        $ua->cookie_jar( {} );

        # Выполняем первый запрос (страница авторизации)
        my $response = $ua->get('https://ihelper.nnov.mts.ru/SelfCarePda/Security.mvc/LogOn?returnLink=https://ihelper.nnov.mts.ru/SelfCarePda/Home.mvc');
        # Сохраняем полученные куки
        $ua->cookie_jar->extract_cookies($response);
        # Запоминаем реферер
        $ua->default_header(Referer => 'https://ihelper.nnov.mts.ru/SelfCarePda/Security.mvc/LogOn?returnLink=https://ihelper.nnov.mts.ru/SelfCarePda/Home.mvc');

        # Второй запрос - авторизация
        $response = $ua->post(
                'https://ihelper.nnov.mts.ru/SelfCarePda/Security.mvc/LogOn?returnLink=https%3A%2F%2Fihelper.nnov.mts.ru%2FSelfCarePda%2FHome.mvc',
                        {
                                username => $server_user,
                                password => $server_pass,
                        }
                );                
        # Снова сохраняем куки
        $ua->cookie_jar->extract_cookies($response);
        # Запоминаем реферер
        $ua->default_header(Referer => 'https://ihelper.nnov.mts.ru/SelfCarePda/Security.mvc/LogOn?returnLink=https%3A%2F%2Fihelper.nnov.mts.ru%2FSelfCarePda%2FHome.mvc');

        # Третий запрос - собственно страница с информацией
        $response = $ua->get('https://ihelper.nnov.mts.ru/SelfCarePda/Home.mvc');

        # Извлекаем данные о балансе
        if ($response->content =~ m{<strong><strong>(\d+?(?:\.\d+?)?)</strong>}) {
                $rv = $1;
        }
};
# Если что-то пошло не так
if (my $error = $@) {
        # Желающие могут дописать обработку ошибок
}
print "$rv\n";

Сохраним скрипт как ~/scripts/balance_mts.pl. Работает он аналогично предыдущим двум.

Теперь надо организовать взаимодействие этих скриптов и Conky. Для этого нужно выполнить команду:

crontab -e

И добавить в свой crontab примерно вот такие строки:

# Получение баланса НСС и сохранение его в кэше
15	*	*	*	*	/home/moose/scripts/balance_ncc-volga.pl > /home/moose/.balance_ncc-volga

# Получение баланса Билайн и сохранение его в кэше
17	*	*	*	*	/home/moose/scripts/balance_beeline.pl > /home/moose/.balance_beeline

# Получение баланса МТС и сохранение его в кэше
19	*	*	*	*	/home/moose/scripts/balance_mts.pl > /home/moose/.balance_mts

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

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

$hr
Balance NCC-Volga: ${exec /bin/cat /home/moose/.balance_ncc-volga}
Balance Beeline:   ${exec /bin/cat /home/moose/.balance_beeline}
Balance MTS:       ${exec /bin/cat /home/moose/.balance_mts}

У автора этих строк результат выглядит примерно вот так:

Conky с отображением балансов мобильных телефонов

Если у вас другой оператор и/или другой регион - скрипты придётся править под ваши условия. Здесь показана только основная идея.

На этом всё. Приятной вам работы!

Ключевые слова: conky, баланс, МТС. Билайн, НСС, скрипт, perl.

Комментарии:

Anonymous 2011-01-29 19:24:39 (#)

Не работает если баланс отрицательный

MooSE 2011-01-29 22:00:24 (#)

Цитата:

Не работает если баланс отрицательный


Допускаю. Но я никогда не зарываюсь в минус. А те кто зарываются вполне смогут поправить регулярники.

Anonymous 2011-02-03 11:43:19 (#)

В Конки можно сразу добавить что-то типа
Билайн: ${execi 2600 perl /home/pa/.scripts/balance_beeline.pl} руб.
И не заморачиваться с Кроном и созданием дополнительных файлов.

MooSE 2011-02-04 01:42:48 (#)

Цитата:

В Конки можно сразу добавить что-то типа
Билайн: ${execi 2600 perl /home/pa/.scripts/balance_beeline.pl} руб.
И не заморачиваться с Кроном и созданием дополнительных файлов.


Спасибо за execi. Как-то не заметил эту команду при чтении документации conky.

Anonymous 2011-02-06 20:00:49 (#)

я на php сделал так:
<?   
$tempFile = tempnam ("", "COOK_");

 function fcurl($urlstart,$urlfinish,$post,$tempFile) 
     {
          $cur = curl_init(); 
          curl_setopt($cur, CURLOPT_URL, $urlstart);
          curl_setopt($cur, CURLOPT_COOKIEJAR, $tempFile);
          curl_setopt($cur, CURLOPT_COOKIEFILE, $tempFile);
          curl_setopt($cur, CURLOPT_USERAGENT, "Opera/10.00 (Windows NT 5.1; U; ru) Presto/2.2.0");
          curl_setopt($cur, CURLOPT_REFERER, $urlfinish);
          curl_setopt($cur, CURLOPT_POST, 1);
          curl_setopt($cur, CURLOPT_POSTFIELDS, $post);
          curl_setopt($cur, CURLOPT_HEADER, 0); 
          curl_setopt($cur, CURLOPT_SSL_VERIFYPEER, 0);
          curl_setopt($cur, CURLOPT_SSL_VERIFYHOST, 0);
          curl_setopt($cur, CURLOPT_FOLLOWLOCATION, 1);
          curl_setopt($cur, CURLOPT_RETURNTRANSFER,1);
          $rez = curl_exec($cur); 
          curl_close($cur);
          return $rez;
     };

$nomer = '**********';
$pasport = '*******';

$us = 'https://ihelper.mts.ru/selfcare/logon.aspx';
$uf = 'https://ihelper.mts.ru/selfcare/logon.aspx';
$p = '0';
$r = fcurl($us,$uf,$p,$tempFile);

preg_match("/id=\"__VIEWSTATE\".*\"(.*?)\"/", $r, $matches);
$post1=$matches[1];
$post1 = urlencode($post1);

$p = "__VIEWSTATE=$post1&ctl00%24MainContent%24tbPhoneNumber=$nomer&ctl00%24MainContent%24tbPassword=$pasport&ctl00%24MainContent%24btnEnter=%D0%92%D0%BE%D0%B9%D1%82%D0%B8";
$us =  'https://ihelper.mts.ru/selfcare/logon.aspx';
$uf = 'https://ihelper.mts.ru/Selfcare/welcome.aspx';
$r = fcurl($us,$uf,$p,$tempFile);

$us = 'https://ihelper.mts.ru/selfcare/account-status.aspx';
$uf = 'https://ihelper.mts.ru/selfcare/account-status.aspx';
$p = '0';
$r = fcurl($us,$uf,$p,$tempFile);
//$r = iconv("UTF-8", "Windows-1251", $r);

preg_match("/<span id=\"customer-info-balance\"><strong>(.+?)<\/strong>/", $r, $matches);
$str=str_replace('\r\n','',$matches[1]);
echo trim($str);
?>

Alex 2011-02-18 09:54:30 (#)

На хабре тоже самое к nagios прикручивают: http://habrahabr.ru/blogs/development/113878/

MooSE, ты так не делал?

MooSE 2011-02-18 10:40:49 (#)

Цитата:

На хабре тоже самое к nagios прикручивают: http://habrahabr.ru/blogs/development/113878/

MooSE, ты так не делал?


Нет:) А надо? По идее можно. Мне не нравится что личные кабинеты мобильных операторов отвечают с о-о-очень большой задержкой и к тому же бывают случаи когда не отвечают вообще:)

flags8192 2011-03-17 07:43:41 (#)

для МТС юзаю так:
#!/bin/sh -e
USERNAME=`whoami` ; T1="root"
if [ "$T1" = "$USERNAME" ]; then 
echo  'Please do not run this script as root' ; exit
fi

# Input: LOGIN, PASSWORD
# Output: account balance
# e.g. LOGIN=9596583576 PASS=xxxxxx mts

request()
{
	wget \
		--load-cookies /tmp/cookies.txt \
		--save-cookies /tmp/cookies.txt \
		--keep-session-cookies \
		--quiet \
		$@
}

request -O /tmp/1.html https://ihelper.mts.ru/SELFCAREPDA/Security.mvc/LogOn
request -O /tmp/2.html --post-data="username=$LOGIN&password=$PASS" https://ihelper.mts.ru/SELFCAREPDA/Security.mvc/LogOn

sed -ne '/<br\/>Баланс:/ { s,.*>\([0-9.]*\)</.*$,\1,; p }' </tmp/2.html


Anonymous 2011-09-10 15:38:51 (#)

~$ ./balance_ncc-volga.pl
Unknown

И всегда возвращает только это.

Подскажите пожалуйста как исправить

MooSE 2011-09-11 00:52:14 (#)

Цитата:

~$ ./balance_ncc-volga.pl
Unknown

И всегда возвращает только это.

Подскажите пожалуйста как исправить


Какой город?

UPD: Судя по твоему IP ты из чувашии. Мой скрипт подходит для татарстана. Проверь адрес личного кабинета. Возможно ещё регулярники придётся подправить.

Anonymous 2011-09-11 20:28:07 (#)

MooSE, Да, город Чебоксары.
Адрес личного кабинета верен. Насчёт регулярок, я перл не знаю. :(

Посмотрел личный кабинет, в нём есть:
<input type="hidden" name="balance" id="balance" value="1.05">

MooSE 2011-09-11 22:03:46 (#)

Цитата:

MooSE, Да, город Чебоксары.
Адрес личного кабинета верен. Насчёт регулярок, я перл не знаю. :(

Посмотрел личный кабинет, в нём есть:
<input type="hidden" name="balance" id="balance" value="1.05">


Попробовал твою строку - вполне обработалась моим регулярником. Если доверяешь то можешь кинуть в личку свой логин и пароль, а так же адрес вашего личного кабинета - попробую отладить.

Anonymous 2011-10-08 19:11:26 (#)

спасибо конечно, но я уже разобрался сам, сделал на баше.

Anonymous 2014-11-06 23:10:56 (#)

Скрипт сделал исполняемым chmod +x balance_mts.pl

Anonymous 2014-11-06 23:29:51 (#)

Цитата:

спасибо конечно, но я уже разобрался сам, сделал на баше.

Как сделали не подскажите, мой город Махачкала республика Дагестан?.

Anonymous 2014-11-16 20:28:39 (#)

Билайна и Мегафона.
У меня есть наработки по этому поводу.
Может буду чем полезен вам, но увы у меня не получается до конца доделать.
http://searchengines.guru/showthread.php?t=873964

Anonymous 2014-11-16 20:29:50 (#)

Также мне понравился аккуратный вариант предложенные на хабре
http://habrahabr.ru/post/156581/
Но увы и там все старое.

Anonymous 2014-11-16 20:33:58 (#)

Предпочел делать на bash, перл мне не знаком к сожалению.
Использовал curl и wget. Сам curl отображает только каркас страницы, скрипты и прочее он не видит.

Anonymous 2014-11-27 22:36:19 (#)

Для Билайна пробовал, но там все сложнее оказалось. Баланс формируется аяксом.
	_WARN=`echo $_RESPONSE | grep "messages-error"`
	if [ "$_WARN" == "" ];
	then
		_BALANCE=`echo $_RESPONSE | egrep -o "<span class=\"price[^\"]?\">[^<]+<span[^>]+>" | sed -e 's@<[^>]*>@@g' -e 's@\s*@ @' -e 's@\ @ @g' -e 's@^\s*@@'`

		if [ "$_BALANCE" != "" ];
		then
			echo "$_BALANCE" | sed -e 's@\..*@.@' -e 's@,@.@'
		else
			echo "Error: balance not avaible"
		fi
	else
		echo "Error: incorrect login or password"
	fi

Выдает "Error: balance not avaible", потому что баланс пуст.
К примеру fiddler выдал мне такой запрос
javax.faces.partial.ajax=true&javax.faces.source=j_idt582%3Aj_idt584%3Aj_idt585&javax.faces.partial.execute=%40all&javax.faces.p...

Также fiddler позволяет выгружать сессии в bat файл.
Выгрузил и пробовал выполнить то что выгрузилось, но увы.

MooSE 2014-12-09 06:36:02 (#)

Честно говоря материал сильно устарел. И я не уверен что хочу заниматься актуализацией. Но за сборник рецептов в комментах - спасибо:)

Anonymous 2014-12-11 11:44:26 (#)

Очень жаль что актуализировать не будете!.

Anonymous 2014-12-11 21:27:44 (#)

Спасибо Вам за столь интересную статью, привет из Дагестана!
Удачи Вам!
Новый комментарий



© 2006-2016 Вадим Калинников aka MooSE