Сидя на работе иногда мне хочется узнать кто из друзей сейчас онлайн в MailАгенте. Но подключаться к сети неохота, т.к. потом кто-нибудь увидев меня онлайн обязательно напишет "Привет", который я не могу оставить без ответа, дальше другие тоже активно подключатся к чату и работа надолго приостанавливается.
Все знают, что на странице профиля МойМир по адресу типа http://my.mail.ru/%domain%/%username% рядом с именем есть маленький рисунок, показывающий статус пользователя в агенте. Достается этот рисунок по адресу http://status.mail.ru?%email_of_user%. Что же, задача тривиальна, можно отправить HTTP-запрос на этот адрес и разобрать бинарные данные, предварительно просмотрев все возможные рисунки статусов например в HEX-редакторе.
Однако в кэше firefox (кстати попробуйте набрать about:cache) я заметил другой урл - http://status.mail.ru/batch.js?user1@mail.ru,user2@mail.ru,user3@mail.ru. Открыв его в браузере я увидел ответ наподобие этой:
MRIM.update('102101');
Немного поигравшись со списком емейлов, я выяснил, что каждая цифра является статусом для каждого емейла в списке соответственно. 0-оффлайн, 1-онлайн, 2-отошел. Хотя может есть и другие статусы.
В общем вот класс на php (нужен curl):
Mail.ru status checker
class StatusChecker { const MRA_URL = 'http://status.mail.ru/batch.js'; public static function describe($statusCode) { switch ($statusCode) { case 0: return 'Оффлайн'; case 1: return 'Онлайн'; case 2: return 'Онлайн (отошел)'; default: return 'Онлайн (?)'; } } public function checkStatus($emails) { } return FALSE; } $result = FALSE; $c = 0; foreach ($emails as $email) { $result[$email] = $m[1][$c++]; } } return $result; }- }
Небольшие пояснения - методу checkStatus можно передать массив проверяемых емейлов или один емейл, далее составляется URL, ставим нужные опции curl и делаем запрос, ответ парсится регекспом.
Теперь можно написать:
StatusChecker в деле :)
$checker = new StatusChecker(); // Загружаем $emails например из файла foreach ($checker->checkStatus($emails) AS $email => $code) { print $email . ': ' . StatusChecker::describe($code) . "\n"; }
P.S.: можно было и через fopen (при включенном allow_url_fopen) не используя curl, но я как-то не подумал...