Следим за голосованием на «Россия 10»

в 8:35, , рубрики: data mining, php, голосование, метки: ,

Как и многие россияне, в последнее время я каждый день захожу проголосовать на сайт 10russia.ru. Если кто не в курсе, Россия 10 — всероссийский проект, в рамках которого каждый может проголосовать за свой любимый географический или архитектурный объект в России. Задача проекта – выбор десяти новых визуальных символов России.
Мне показались странными цифры в ТОП2 в голосовании, и я решил посмотреть, как они меняются. Было мало времени, и на скорую руку написал маленький парсер, который сохраняет раз в 2-3 секунды данные по количеству голосов на сайте и смс. Для отображения этих данных создал сайт (За основу был взят дизайн и основа графика отсюда habrahabr.ru/post/176547/. Надеюсь, автор будет не против ). Денег не хотелось тратить, а в распоряжении был только личный слабенький VDS, который бы быстро лёг, если бы данные генерировались динамически. Поэтому решено было обойтись статическим html и генерацией по крону json файлов. Интересно будет посмотреть, какую нагрузку выдержит VDS без изменения текущей конфигурации (CPU 300MHz, RAM 128 Mb), учитывая, что там крутится два небольших сервиса и один малопосещаемый сайт. В конце голосования выложу, если кому надо, все полученные данные голосования.

Листинг парсера

<?php
set_time_limit(0);
function handleError($errno, $errstr, $errfile, $errline, array $errcontext) {
    if (0 === error_reporting()) {
        return false;
    }
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler('handleError');
mysql_connect('localhost', 'login', 'password');
mysql_select_db('10russia');

function addNewData($html, $key) {
    $site = $sms = 0;
    if( preg_match('/<span id="count_votes_site">([^<]+)/iu', $html, $match) ) {
        $site = (int)str_replace(' ', '', $match[1]);
    }
    if( preg_match('/<span id="count_votes_sms">([^<]+)/iu', $html, $match) ) {
        $sms = (int)str_replace(' ', '', $match[1]);
    }
    if($site && $sms) {
        $all = $sms + $site;
        mysql_query("INSERT INTO stat(`key`, sms, site, `all`) VALUES('$key', $sms, $site, $all)");
    }
}

$urls = array(
    'object_31' => 'http://10russia.ru/object_31',
    'object_61' => 'http://10russia.ru/object_61'
);
while(true) {
    foreach($urls as $key => $url) {
        try {
            $result = file_get_contents($url);
            addNewData($result, $key);
            sleep(1);
        } catch(Exception $e) {}
    }
}

Листинг скрипта для создания по крону json файлов

<?php
mysql_connect('localhost', 'login', 'password');
mysql_select_db('10russia');

$keys = array(
    'object_31' => 'object31.json',
    'object_61' => 'object61.json'
);

foreach($keys as $key => $file) {
    $filename = dirname(__FILE__) . '/' . $file . '.tmp';
    $fLink = fopen($filename, 'w');
    if($fLink) {
        $result = mysql_query("SELECT `date`, `all` FROM stat WHERE `key`='$key' ORDER BY id ASC");
        fwrite($fLink, "[n");
        $row = mysql_fetch_assoc($result);
        $first = true;
        do {
            $str = '';
            if(!$first){
                $str = ",";
            } else {
                $first = false;
            }
            fwrite($fLink, $str . '['.strtotime($row['date']) . "000,{$row['all']}]" );
        } while($row = mysql_fetch_assoc($result));
        fwrite($fLink, "]");
        fclose($fLink);
        rename($filename, dirname(__FILE__) . '/' . $file);
    }
}

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

Интересные моменты на графиках

Максимальный прирост за 30 минут
Максимальный прирост за 30 минут

Общая динамика за всё время мониторинга
Общая динамика за всё время мониторинга

ВГТРК

Я надеюсь что не создал для вас больших проблем, учитывая большую популярность проекта, вы, думаю, были готовы к большому потоку посетителей. Кстати, если кто ищет в Москве работу системного администратора, то создатели сайта ищут себе сотрудников, уже не совсем оригинальным, но редким способом:
Работа

Ссылки

Посмотреть, что у меня получилось, ознакомиться с детальной статистикой голосования и сделать выводы: http://10russia.miningdata.ru/

Автор: Nord001

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js