<% ASP на блюдечке %>. Часть 18

Создаем систему сбора и обработки статистики посещаемости Web-сайта своими руками

Рубен Садоян (rouben@iname.com)

Введение

Небольшое лирическое отступление

Методы увеличения популярности сайта

Внесем ясность

Организация работ

Создание и подготовка базы данных

Интеграция системы в уже готовый сайт

Когда и где фиксировать посещения?

Что такое Global.asa

Регистрация посещений — файл global.asa

Сервисные функции системы — файл Utils.asp

Главная страница системы — файл Index.asp

Основное меню системы — файл StatMain.asp

Статистика уникальных посещений (хостов) — файл Hosts.asp

Статистика всех посещений (хитов) — файл Hits.asp

Графическое представление статистики (хитов) по датам — файл HitsGraph.asp

Заключение

Введение

Популярность того или иного сайта Всемирной паутины обусловливается множеством самых разнообразных причин. Обобщая, можно сказать, что популярность — это прежде всего огромное количество посещений сайта, и здесь необходима ясность. Сразу же возникает масса разнообразных вопросов: что считать посещением? откуда «пришел» пользователь? какие из страниц его больше всего заинтересовали? как часто он заглядывал на тот или иной сайт? какова среднесуточная нагрузка на сервер? какое время суток можно считать пиковым с точки зрения посещаемости?

Согласитесь, что ответы на эти и многие другие вопросы позволят Web-мастерам настроить тот или иной ресурс Всемирной сети  на конкретную аудиторию пользователей целевым образом и добиться тем самым увеличения количества посетителей, а следовательно, и популярности.

Решению этой проблемы — созданию системы учета и анализа посещений — и посвящена настоящая статья.

В начало В начало

Небольшое лирическое отступление

По информации кинокомпании New Line Cinema, популярность сайта экранизации книги «Властелин колец» (http://www.lordoftherings.net) превысила самые смелые ожидания создателей. Так, к примеру, в январе 2002 года количество посетителей составило 383 тыс. человек, а в феврале этого года на сайте побывали 314 тыс. человек. С января компания ABC Interactive, осуществляющая измерение посещаемости сайта, насчитала на нем 350 млн. хитов (посещений).

В начало В начало

Методы увеличения популярности сайта

Cистематический анализ статистики посещений сайта — это инструмент, позволяющий грамотно и своевременно реагировать на изменения посещаемости. Под реакцией прежде всего нужно понимать следующие действия:

  1. Обновление материалов сайта. Лучше не пользоваться стандартными фразами. Оригинальность новостей и определенная доля философствований (конечно, при наличии способностей) имеют большое значение. Новости или хотя бы их анонсы желательно вынести на основную страницу. Для оригинальности можно писать не только дату обновления, но и время с точностью до минуты.
  2. Обмен баннерами с сайтами такой же популярности (не ниже). Особенно — на главные страницы, на специальном и самом видном месте.
  3. Сотрудничество с популярными сайтами. Например, можно договориться о размещении на главных страницах рекламных баннеров сроком до 1 месяца. Прошел месяц — ищите другого сайта-партнера. Таким образом вы будете привлекать постоянных посетителей сайта-партнера, которые, возможно, станут и вашими.  
  4. Размещение баннерной рекламы. Это эффективно в случаях, если ваш баннер имеет CTR (коэффициент полезного действия) свыше 4%, баннер меняйте с периодичностью 1-2 месяца.  
  5. Организация на сайте интересных викторин. Желательно, если они будут  с призами.
  6. Использование адреса вашего сайта с кратким описанием. Настройте вашу почтовую программу так, чтобы это приписывалось в конце письма. Если вы часто посылаете письма большому количеству людей, это будет весьма эффективно.
  7. Проведение регулярных кампаний по почтовой рассылке информации о сайте. Следует охватить большое количество потенциально интересующихся клиентов по электронной почте с помощью специальных программ (Bulk Mailing).
  8. Неназойливая и интригующая реклама на нескольких популярных форумах и/или чатах. Это можно проводить с периодичностью, например, раз в неделю. Если же посетители форума или чата негативно отзываются по поводу  рекламы, лучше все прекратить, иначе вы будете пользоваться дурной славой.
  9. Индексация сайта в разнообразных поисковых машинах. Действуйте как в зоне .ru (Rambler, Yandex, Aport…), так и в зоне .com (AltaVista, Yahoo, HotBot, Lycos…) для успешного нахождения вашего сайта этими поисковыми машинами.

Этот список можно продолжать, однако эти методы являются основными.

В начало В начало

Внесем ясность

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

Посещение — однократное пребывание пользователя на том или ином ресурсе, причем это может быть как один и тот же пользователь, так и несколько разных. Такое посещение иногда обозначают словом «хит» (от англ. hit).

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

Клиент — под клиентом мы будем понимать тип, версию браузера и операционную систему, под управлением и с помощью которых было осуществлено посещение или уникальное посещение ресурса.

Реферер (referer) — адрес Всемирной сети, где пользователь находился непосредственно до осуществления посещения или уникального посещения данного ресурса (это, как правило, поисковые машины). Таким образом можно определять эффективность той или иной поисковой машины либо ссылки во Всемирной сети применительно именно к данному сайту.

Страна принадлежности хоста — страна, в доменной зоне которой находится тот или иной пользователь (вычисляется на основании IP-адреса путем декодирования его в доменное имя).

В начало В начало

Организация работ

Для начала представим себе, что нам предстоит сделать для фиксирования всевозможных посещений нашего гипотетического Web-сайта:

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

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

В-третьих, необходимо разработать подсистему контроля над доступом к статистической информации во избежание несанкционированного доступа.

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

В начало В начало

Создание и подготовка базы данных

Для организации хранения данных о посещениях нам понадобятся две таблицы. В первой мы будем хранить хиты наших пользователей, во второй — хосты.

Таблица хитов будет хранить количество хитов по дням следующим образом: .

Таблица хостов будет хранить количество хостов по датам посещения и с учетом IP-адреса и клиента следующим образом: .

 В целях организации удобного встраивания системы в уже существующие сайты рекомендуется спланировать еще одну таблицу — для организации хранения имен и паролей пользователей, которым будет делегировано право просмотра и анализа статистики по посещениям данного ресурса: .

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

  • запустите программу-конфигуратор источников данных (Data Sources ODBC) — Start->Settings->Control Panel->Administrative Tools->Data Sources ODBC;
  • перейдите во вкладку System DSN и создайте новый источник данных, нажав на Add…;
  • в появившемся списке драйверов выберите драйвер баз данных — Microsoft SQL Server и нажмите на Next;
  • в строке Data Source Name задайте имя нашей базы данных — в нашем случае это будет SiteStat (по этому имени мы в дальнейшем будем обращаться к базе);
  • в строке Server укажите сервер, к которому будет осуществлено подключение, и нажмите на Next;
  • выберите режим аутентификации With SQL Server…, задайте имя пользователя и пароль для подключения к SQL-серверу, определите протокол связи с сервером (кнопка Client Configuration — TCP/IP) и два раза нажмите на Next, после чего нажмите на Finish;
  • посмотрим на появившуюся перед вами статистику о проделанных действиях, а для проверки источника данных можете воспользоваться кнопкой Test Data Source;
  • в итоге перед вами появится строка в списке источников данных в вашей системе.

Теперь, когда база данных готова, можно переходить к созданию системы статистики.

В начало В начало

Интеграция системы в уже готовый сайт

Cама по себе система сбора и анализа статистики не имеет смысла: кому нужен сайт, предназначенный исключительно для сбора и обработки посещаемости? Поэтому ключевым моментом в разработке такой системы является в первую очередь простота и удобство встраивания последней в уже существующий ресурс всемирной компьютерной сети. Следовательно, моментам, связанным с упрощением встраивания системы в уже готовые сайты, нужно уделить особое внимание.

В начало В начало

Когда и где фиксировать посещения?

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

В начало В начало

Что такое Global.asa

Global.asa позволяет выполнять определенные скрипты в начале работы клиентской сессии или при инициализации IIS. Более того, допустимо использовать множественные файлы Global.asa. Однако следует учитывать, что ASP-скрипт ищет самый близкий (расположенный в том же каталоге) файл Global.asa и использует именно его.

По сути, этот файл может содержать четыре скрипта: первый будет выполняться при инициализации службы IIS/PWS (Application_OnStart), второй — при остановке службы IIS/PWS (Application_OnEnd) (обычно эти первые два скрипта отрабатывают в процессе перезагрузки компьютера), а остальные два скрипта выполняются дополнительно — при инициализации сессии пользователя (Session_OnStart) и по ее окончании (Session_OnEnd). Данная схема очень напоминает пары «конструктор-деструктор». Неспроста всякая переменная, которая должна быть использована (например, в текущей сессии), может быть инициализирована в Session_OnStart, с тем чтобы быть использованной в процессе работы сессии, она же уничтожается (обнуляется) в Session_OnEnd.

Global.asa не может содержать тэгов HTML. Недопустимо использование JavaScript. Не рекомендуется писать файл Global.asa с помощью каких-либо HTML-редакторов — для этого гораздо лучше использовать NotePad. И еще один совет: прежде чем вставлять скрипт в файл Global.asa, попробуйте его в работе в обычном ASP-файле

<OBJECT RUNAT=Server
SCOPE=Session
ID=Tool1
PROGID="MSWC.Tools">
</OBJECT>
 
<SCRIPT LANGUAGE = "VBScript" RUNAT="Server">
Sub Session_OnStart
Dim strUserLogon
Dim StrUserSecurity
' Эти переменные сессии будут держать
' значения имени пользователя ( logon) и права его доступа.
strUserLogon = Request.ServerVariables("USER_LOGON" )
strUserSecurity = "PUBLIC"
End Sub
 
Sub Session_OnEnd
' Этот код уничтожает компонент Tools для текущей сессии.
Set Tool1 = Nothing
'А этот обнуляет переменные сессии.
strUserLogon = ""
strUserSecurity = ""
‘ Внимание! Данный код применять в этом смысле совсем не обязательно,
' так как объекты будут выгружены из памяти Web-сервером
' автоматически по закрытии текущей сессии.
End Sub
 
</SCRIPT>
В начало В начало

Регистрация посещений — файл global.asa

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

  1. Запись в таблицу хитов всех посещений в подневном режиме.
  2. Запись в таблицу хостов уникальных хостов с фиксацией даты посещения, клиента и IP адреса посетителя.
<SCRIPT LANGUAGE = VBScript RUNAT=Server>
    <!-- Metadata type="typelib" File="c:\program files\common    files\system\ado\msado15.dll" -->
   </SCRIPT>
   <OBJECT RUNAT=Server SCOPE=Session ID=MyInfo PROGID="MSWC.MyInfo"></OBJECT>
   
   <script language="vbscript" runat=server>
   Sub Application_OnStart
    Session.TimeOut = 1
   End Sub
   
   Sub Application_OnEnd
    Session.Abandon
   End Sub
   
   Sub Session_OnStart
    Session.TimeOut = 1
    dim strConn, objConn
    dim dsn,conn,rs,sql
   …

Объявим переменные, посредством которых будем осуществлять соединение с базой данных

 …
   dsn = "DSN=SiteStat; UID=SiteStat;PWD=SiteStat;database=SiteStat"
    set conn = server.createobject("adodb.connection")
    set rs = server.createobject("adodb.recordset")
    conn.open dsn
   …

Получим IP-адрес пользователя и его клиент:

 ' Insert  incoming IP & Client
    dim IP, Browser
    IP = Request.ServerVariables("REMOTE_ADDR")
    Browser = Request.ServerVariables("HTTP_USER_AGENT")
   
   …

Добавим запись в таблицу хостов, если IP-адреса с таким значением там не обнаружено:

 …
   
    sql = "select * from Hosts where IPAddress='" & IP &    "'"
    rs.open sql, conn, adOpenStatic, adLockOptimistic
    if rs.EOF then
      rs.addnew
      rs("IPAddress") = IP
      rs("HTTPClient") = Browser
      rs.update
    end if
    rs.close
   
   …

Вычислим сессионную переменную с суммарным количеством хитов за все время существования сайта для отображения на главной страничке:

 …
    ' ---------------------------------
    sql = "select SUM(Hits) As HitsNum from Hits"
    rs.open sql, conn
    Session("Hits") = rs("HitsNum")
    rs.close
   
   …

Увеличим значение хитов за текущий день в таблице хитов. Здесь используются операторы работы с датами языка Transact-SQL. Для того чтобы нижеследующий код был вполне понятен, приведем краткую справку:

Day(datetime) —  возвращает значение дней с начала месяца для заданной даты datetime;

Month(datetime) — возвращает значение месяцев с начала года для заданной даты datetime;

Year(datetime) —  возвращает значение лет для заданной даты datetime;

GetDate() —  возвращает текущую дату и время на сервере.

…
    ' ---------------------------------
    sql = "SELECT * FROM Hits WHERE Day(DayDate) = DAY(Getdate()) "
    sql = sql & "AND MONTH(DayDate) = MONTH(GetDate()) AND YEAR(DayDate)    = YEAR(GetDate())"
    rs.open sql, conn
    If NOT rs.EOF THEN
      sql = "UPDATE Hits SET Hits = Hits + 1 WHERE Day(DayDate)    = DAY(Getdate()) "
      sql = sql & "AND MONTH(DayDate) = MONTH(GetDate()) AND    YEAR(DayDate) = YEAR(GetDate())"
      conn.execute(sql)
    Else
      sql = "INSERT INTO Hits (DayDate, Hits) VALUES (GETDATE(),    1)"
      conn.execute(sql)
    End If
    rs.close
   
   …

Вычислим сессионную переменную с суммарным количеством хостов за все время существования сайта для отображения на главной страничке:

 …
    
   ' Count hosts ---------------------
    sql = "select COUNT(*) AS HostsNum FROM Hosts"
    rs.open sql, conn, adOpenStatic, adLockOptimistic
    Session("Hosts") = rs("HostsNum")
    rs.close
   
   …

Закроем соединение с базой данных и обнулим переменные:

 …
    ' ---------------------------------
    set rs = nothing
    conn.close
    set conn = nothing
   End Sub 
Sub Session_OnEnd
  Session.Abandon
 End Sub
 </script>  
В начало В начало

Сервисные функции системы — файл Utils.asp

Прежде всего, целесообразно вынести сервисные функции в отдельный файл, который мы будем «включать» в код по мере необходимости (это избавит нас от повторений часто используемых функций и частей кода):

<SCRIPT LANGUAGE = VBScript RUNAT=Server>
  <!-- Metadata type="typelib" File="c:\program files\common files\system\ado\msado15.dll" -->
 </SCRIPT>  

Функции подключения к базе данных и отключения от нее:

 …
   
   <%
    option explicit
    response.buffer=true
    Response.Buffer = true
   
    dim strConn, objConn
    dim dsn,conn,rs,sql, conn1, rs1, sql1 
 dsn = "DSN=SiteStat; UID=SiteStat;PWD=SiteStat;database=SiteStat"  
 Sub Connect()
   set conn = server.createobject("adodb.connection")
   set rs = server.createobject("adodb.recordset")
   conn.open dsn
  End Sub  
 Sub Connect1()
   set conn1 = server.createobject("adodb.connection")
   set rs1 = server.createobject("adodb.recordset")
   conn1.open dsn
  End Sub
 
  Sub Close()
    rs.close
    set rs = nothing
    conn.close
    set conn = nothing
  End Sub  
 Sub Close1()
      rs1.close
      set rs1 = nothing
      conn1.close
      set conn1 = nothing
    End Sub
   
   …

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

 …
   
    Sub secure_general()
     If session("status") <> "admin" Then
      Response.Redirect "error.htm"
     End If
    End Sub
   %> 
В начало В начало

Главная страница системы — файл Index.asp

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

<!--#include file="utils.asp"-->
   <%
    dim useraction,username,password,forumid
   
   …

Анализ пользовательского ввода таков: из введенного имени пользователя и пароля удаляются пробелы и производится выборка из таблицы пользователей системы с совпадением имени и пароля с заданными. В случае совпадения инициализируется сессионная переменная, делегирующая доступ к остальным страничкам статистики, а при несовпадении выводится сообщение об ошибке:

 …
   
    useraction = request("action")
   
    Select Case userAction
     Case "login"
        username = Trim (request.form("username"))
        password = Trim (request.form("password"))
        Call Connect()
        sql="select * from StatUsers where username='"&username&"'    and password='"&password&"'"
        rs.open sql,conn
        If rs.eof AND rs.bof Then
         Response.Write "<b>Проверьте правильность    ввода имени и/или пароля</b><br><br>"
        Else
         Session("status") = "admin"
         Response.Redirect "StatMain.asp"
        End If
        Call Close()
    End Select
   %> 

Реализация формы ввода имени и пароля выглядит следующим образом:

 …
   
   <html>
   <head>
   <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
   <link rel="stylesheet" href="grc.css" type="text/css">
   <title>SiteStat - Администрирование</title>
   </head> 
<body>
 <div align="center">
 <h2><p align="center">Статистика посещений Web-сайта <a href="http://www.SiteStat.ru">www.SiteStat.ru</a></p></h2>
 <hr>
 <p>Введите Login и пароль доступа к системе статистики</p>
 <table border=1 bgcolor = "#FFFFeF" width="270">
 <form action="index.asp?action=login" method="post">
 <tr><td colspan=2 align = center>Администратор системы</td></tr>
 <tr><td>Имя:</td><td>
 <input type="text" name="username" size=20 maxlength=20>
 </td></tr>
 <tr><td>Пароль:</td><td>
 <input type="password" name="password" size=20 maxlength=20>
 </td></tr>
 <tr><td colspan=2 align=center><input type="submit" name="submit" value="Вход"></td></tr>
 </form>
 </table>
 <br>
 <hr>
 <a href="javascript:history.back(-1)">Назад</a> | <a href="../main.asp">Главная страница сайта</a>
 </div>
 </body>
 </html>  
В начало В начало

Основное меню системы — файл StatMain.asp

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

<!--#include file="utils.asp"-->
 <%
  Call secure_general()
 %>            
<html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <link rel="stylesheet" href="grc.css">
 <title>ASP на блюдечке - часть 18. - статистика посещений</title>
 </head>  
<body>
 <h2><p align="center">Статистика посещений Web-сайта <a href="http://www.SiteStat.ru">www.SiteStat.ru</a></p></h2>
 <hr>  
<div align="center">
   <h3>Выберите режим работы <br><br></h3>
   <p><a href="Hosts.asp">Статистика уникальных посещений    Web-сайта (хосты)</a></p>
   <p><a href="Hits.asp">Статистика всех посещений Web-сайта    (хиты)</a></p>
   <p><a href="HitsGraph.asp">Графическое представление хитов    по датам</a></p>
   <hr>
   <p>
   <a href="javascript:history.back(-1)">Назад</a> | <a    href="../main.asp">Главная страница</a>
   </p>
   </div>
   </body>
   </html>
В начало В начало

Статистика уникальных посещений (хостов) — файл Hosts.asp

Выборка статистики по уникальным посещениям основана на таблице Hosts и содержит выборку всех ее значений отсортированных по дате, начиная с самого последнего хоста:

<!--#include file="utils.asp"-->
 <%
  Call secure_general()
 %>
 
 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <link rel="stylesheet" href="grc.css">
 <title>ASP на блюдечке - часть 18. - статистика посещений</title>
 </head>  
<body>
 <%
  call connect()
  sql="SELECT COUNT(*) AS HostsNum FROM HOSTS"
  rs.open sql,conn
 %>
 
 <h2><p align="center">Статистика посещений Web-сайта <a href="http://www.SiteStat.ru">www.SiteStat.ru</a></p></h2>
 <hr>
 <div align="center">
 <h3>Выборка по уникальным заходам на сайт (по <% = rs("HostsNum")%> хостам)</h3>
 <br>
 <table border=2 width=830 align=center>
   <tr align = left>
     <td colspan = 2 width="170"><h4>Дата посещения</h4></td>
     <td colspan = 2 width="120"><h4>IP-адрес</h4></td>
     <td colspan = 2 width="500"><h4>HTTP-клиент (браузер)</h4></td>
   </tr>
  <%
  rs.close
  sql="SELECT * FROM Hosts ORDER BY DateVisited DESC"
  rs.open sql,conn
  Do While NOT rs.EOF
 %>
   <tr align = left>
     <td colspan = 2>
       <% =rs("DateVisited") %>
     </td>
     <td colspan = 2><% =rs("IPAddress") %>
     </td>
     <td colspan = 2>
       <% =rs("HTTPClient") %>
     </td>
     <% 
  rs.MoveNext
 Loop
 %>
   </tr>
   <%
  call close()
 %>
 </table>
 <br>
 <p>
 <a href="javascript:history.back(-1)">Назад</a> | <a href="StatMain.asp">Главная страница статистики</a>
 </p>
 </div>
 
 </body>
 </html>  
В начало В начало

Статистика всех посещений (хитов) — файл Hits.asp

Выборка статистики по всем посещениям основана на таблице Hits и содержит выборку по дням всех ее значений, отсортированных по дате, начиная с самого последнего хита:

<!--#include file="utils.asp"-->
 <%
  Call secure_general()
 %>  
<html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <link rel="stylesheet" href="grc.css">
 <title>ASP на блюдечке - часть 18. - статистика посещений</title>
 </head>
 <body>
   <%
  call connect()
  sql="SELECT COUNT(*) AS DaysNum, SUM(Hits) As HitsNum FROM Hits"
  rs.open sql,conn
 %>  
<h2><p align="center">Статистика посещений Web-сайта <a href="http://www.SiteStat.ru">www.SiteStat.ru</a></p></h2>
 <hr>
 <div align="center">
 <h3>Выборка по всем заходам на сайт (по <% = rs("HitsNum") %> хитам, имевшим место за <% = rs("DaysNum")%> дней)</h3>
 <br>
 <table border=2 width=830 align=center>
   <tr align = left>
     <td colspan = 2 width="170"><h4>День посещения</h4></td>
     <td colspan = 2 width="500"><h4>Количество хитов</h4></td>
   </tr>
 <%
  rs.close
  sql="SELECT * FROM Hits ORDER BY DayDate DESC"
  rs.open sql,conn
  Do While NOT rs.EOF
 %>
   <tr align = left>
     <td colspan = 2>
       <% =rs("DayDate") %>
     </td>
     <td colspan = 2>
       <% =rs("Hits") %>
     </td>
     <% 
  rs.MoveNext
 Loop
 %>
   </tr>
   <%
  call close()
 %>
 </table>
 <br>
<p>
 <a href="javascript:history.back(-1)">Назад</a> | <a href="StatMain.asp">Главная страница статистики</a>
 </p>
 </div>
 
 </body>
 </html>  
В начало В начало

Графическое представление статистики (хитов) по датам — файл HitsGraph.asp

Выборка статистики по всем посещениям основана на таблице Hits и содержит выборку по дням всех ее значений отсортированных по дате, начиная с самого последнего хита. Страничка реализована в двух режимах: в режиме просмотра по дням и режиме просмотра по месяцам. В каждом из режимов помимо численной информации представлена и графическая информация в виде горизонтальных и вертикальных столбиков соответственно:

<!--#include file="utils.asp"-->
 <%
  DIM ScaleFactor, I, MonthStr, MaxMonthHits, Month, Year
  Call secure_general()
 %>  
<html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <link rel="stylesheet" href="grc.css">
 <title>Централ Партнершип —  статистика посещений</title>
 </head>
 
 <body>
 
 …

Для начала определим суммарное количество хитов и количество дней, в течение которых ведется статистика:

 …  
<%
  call connect()
  sql="SELECT COUNT(*) AS DaysNum, SUM(Hits) As HitsNum FROM Hits"
  rs.open sql,conn
 %>
 
 <h2><p align="center">Статистика посещений Web-сайта <a href="http://www.SiteStat.ru">www.SiteStat.ru</a></p></h2>
 <hr>
 <div align="center">
 <h3>Выборка по всем заходам на сайт (по <% = rs("HitsNum") %> по хитам, имевшим место за <% = rs("DaysNum")%> дней)</h3>
 
 <%
  rs.close  

Затем опросим переменную режима работы и сформируем форму в зависимости от ее значения. Обратите внимание на то, каким образом реализована обработка нажатия на радиокнопки. Submit формы происходит не по нажатии на кнопку Submit (которой в данном случае вообще нет), а непосредственно по переключении режима. Это достигается посредством встраивания кода "javascript:document.ViewStyleForm.submit();" в функцию — обработчик нажатия на радиокнопку OnClick:

 Dim VS
  VS = request("vs")
  If VS = "" THEN VS = 1
 %>  
<table>
   <tr><td>
   <form name="ViewStyleForm" method="post" action="HitsGraph.asp">
   <input type="radio" name="vs" value="1" OnClick="javascript:document.ViewStyleForm.submit();"
   <% If VS = 1 THEN Response.Write "checked" %> >Просмотр по    дням<br>
   <input type="radio" name="vs" value="2" OnClick="javascript:document.ViewStyleForm.submit();"
   <% If VS = 2 THEN Response.Write "checked" %> >Просмотр по    месяцам
   </form>
   </td></tr>
   </table>
   
   …

Далее в зависимости от выбранного режима работы:

<%
  If VS = 1 Then
     Response.Write "<table border=2 width=830 align=center><tr align = left>"
     Response.Write "<td colspan = 2 width='170'><h4>Дата посещения</h4></td>"
     Response.Write "<td colspan = 2 width='660'><h4>Хитов</h4></td></tr>"
 
     sql="SELECT MAX(Hits) AS MaxHits FROM Hits"
     rs.open sql,conn
     ScaleFactor = 650 / rs("MaxHits")
     rs.close  
    sql="SELECT * FROM Hits ORDER BY DayDate DESC"
     rs.open sql,conn  
    I = 1  
    Do While NOT rs.EOF
      Response.Write "<tr align = left><td colspan = 2>"
      Response.Write rs("DayDate")
      Response.Write "</td><td colspan = 2>"
      Response.Write "<img src = images/char"& I &".gif width=" & rs("Hits") * ScaleFactor & " height=10>"
      Response.Write "&nbsp;" & rs("Hits")
      Response.Write "</td>"  
     I = I + 1
      IF I = 11 Then I = 1
     rs.MoveNext
     Loop  
    Response.Write "</tr>"
     call close()  
 Else
 %>  
<table cellspacing=0 cellpadding=0 width=830 height=550 style="BORDER-RIGHT:    rgb(0,0,0) 0px outset; BORDER-TOP: rgb(0,0,0) 0px
   outset; BORDER-LEFT: rgb(128,128,128) 1px outset; BORDER-BOTTOM: rgb(128,128,128)    1px
   outset"vAlign=top width="830"  height=1>
   
   <tr align="left">
   <td width="5">&nbsp;</td>
   
   …

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

 …
   
   <%
     MaxMonthHits = 0 
  sql = "SELECT DISTINCT YEAR(DayDate) * 12 + MONTH(DayDate) AS UniqueMonth FROM Hits"
   rs.open sql,conn
 
   Do While NOT rs.EOF
     Call Connect1()
      sql1="SELECT Hits, MONTH(DayDate) AS Month, YEAR(DayDate) AS Year "
      sql1 = sql1 & " FROM Hits WHERE (YEAR(DayDate) * 12 + MONTH(DayDate)) = "
      sql1 = sql1 & rs("UniqueMonth") & " ORDER BY DayDate"
      rs1.open sql1,conn1
      MonthStr = CStr(rs1("Month")) & "." & CStr(rs1("Year"))
     Call Close1()
     Call Connect1()
      sql1="SELECT SUM(Hits) AS MonthHits FROM Hits WHERE YEAR(DayDate) * 12 + MONTH(DayDate) = " & rs("UniqueMonth")
     rs1.open sql1,conn1
      If MaxMonthHits < rs1("MonthHits") Then MaxMonthHits = rs1("MonthHits")
     Call Close1()
     rs.MoveNext
   Loop   
  rs.close
 
   I = 1
   ScaleFactor = 550 / MaxMonthHits  
  sql = "SELECT DISTINCT YEAR(DayDate) * 12 + MONTH(DayDate) AS UniqueMonth FROM Hits"
   rs.open sql,conn  
  Do While NOT rs.EOF
     Call Connect1()
      sql1="SELECT Hits, MONTH(DayDate) AS Month, YEAR(DayDate) AS Year "
      sql1 = sql1 & " FROM Hits WHERE (YEAR(DayDate) * 12 + MONTH(DayDate)) = "
      sql1 = sql1 & rs("UniqueMonth") & " ORDER BY DayDate"
      rs1.open sql1,conn1
      Month = rs1("Month")
      Year = rs1("Year")
     Call Close1()
     Call Connect1()
 
      sql1="SELECT SUM(Hits) AS MonthHits FROM Hits WHERE YEAR(DayDate) * 12 + MONTH(DayDate) = " & rs("UniqueMonth")
      rs1.open sql1,conn1
      Response.Write "<td width='2' valign='bottom' align='left'>"
      Response.Write "<img src = images/char" & I & ".gif width=20 height="
      Response.Write rs1("MonthHits") * ScaleFactor & "></td>"
      Response.Write "<td width='5' valign='bottom' align='left'>"
      Response.Write "<img src = images/Months/" & Month & ".gif </td>"
     Call Close1()  
    I = I + 1
     If I = 11 Then I = 1
     rs.MoveNext
   Loop   
  rs.close
 %>  
<td width=100%>&nbsp;</td>
 </tr>
 </table>
 
 <%
  End If
 %>  
</table>
 <br>
 <p>
 <a href="javascript:history.back(-1)">Назад</a> | <a href="StatMain.asp">Главная страница статистики</a>
 </p>
 </div>
 
 </body>
 </html>  
В начало В начало

Заключение

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

В этой системе возможно сделать множество усовершенствований, как-то: декодирование предыдущей страницы (страницы–referrer’a, с которой пользователь обратился к данному ресурсу), определение страны, откуда было произведено обращение, вычисление параметров пиковых нагрузок на сервер и т.д. Имеется также пространство для улучшения пользовательского интерфейса с генерацией отчетов в привычной для пользователя форме, для усовершенствования графического интерфейса для аналитической части системы и т.д. (об усовершенствованиях данной системы будет рассказано в одной из последующих частей статьи).

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

В статье использованы материалы сайта http://design.hop.ru/.

КомпьютерПресс 3'2002