Анализ посетителей веб-сайта
Рассмотрим одни из самых простейших и первых скриптов, которые
появились на веб-сайтах - это учет и анализ посетителей сайта. Этим скриптам
необходимо сохранять, редактировать и удалять
информацию на сервере, поэтому без СУБД никак не обойтись. Каждый раз при заходе посетителя
на страницу,
будет вызываться CGI-скрипт счетчика,
который будет записывать информацию об одном посещении в нашу базу.
Ниже приведена таблица, где мы будем хранить информацию о посещении
пользователем страницы нашего сайта:
CREATE TABLE hit (
owner_id int unsigned NOT NULL default '0', // id счетчика
it_date datetime default NULL, // дата посещения
shref varchar(255) default NULL, // сервер, с которого пользователь
// пришел на нашу страницу
href varchar(255) default NULL, // страница сервера, с которой
// пользователь пришел на нашу
// страницу
ip varchar(16) default NULL, // ip-адрес пользователя
os varchar(32) default NULL, // операционная система
browser varchar(32) default NULL,// броузер
version varchar(32) default NULL,// версия броузера
x int unsigned default NULL, // разрешение экрана по горизонтали
y int unsigned default NULL, // разрешение экрана по вертикали
depth int unsigned default NULL, // количество цветов (глубина цвета)
cookie enum('0','1') default '0',// поддерживается ли механизм Cookie
java enum('0','1') default '0', // поддерживается ли java
spage varchar(255) default NULL, // url посещаемого сервера
page varchar(255) default NULL, // url посещаемой страницы
frame enum('0','1') default '0', // страница с фреймом или без
js char(3) default '0' // версия javascript
)
Данная информация собирается простым кодом на JavaScript, см. главу пять, ниже
приведен код счетчика:
<script language="JavaScript">js=10;</script><script language="JavaScript1.1">
js=11;</script><script language="JavaScript1.2">js=12</script>
<script language="JavaScript1.3">js=13;</script>
<script language="JavaScript">
d=document;n=navigator;s=screen;d.cookie="testparam=testvalue";
d.write('<img width=1 height=1 src="http://itsoft.ru/common/counter?id=1' +
'&r='+escape(d.referrer)+
'&n='+escape(n.appName)+
'&v='+escape(navigator.appVersion)+
'&c='+(d.cookie?"1":"0")+
'&f='+((self!=top)?"1":"0")+
'&j='+(n.javaEnabled()?"1":"0")+
'&x='+s.width+
'&y='+s.height+
'&d='+(s.colorDepth?s.colorDepth:s.pixelDepth)+
'&js='+js+
'&o='+n.platform+'&'+Math.random()+'">');
</script>
Обратите внимание, что код на JavaScript состоит из двух блоков. В первом определяется
версия JavaScript, а во втором идет код самого счетчика. Самым последним параметром передается случайное
число, оно не используется, но необходимо, чтобы броузеры и прокси-сервера не кэшировали
наш счетчик. Если бы этого случайного числа не было, то скрипт счетчика вызывался бы только
один раз, при первом заходе пользователя, а в остальных случаях броузер или прокси-сервер
выдавал бы прозрачный GIF из кэша.
Нас интересуют отчеты, которые показывают: количество уникальных посетителей сайта, общее количество
запрошенных страниц, среднее количество страниц, запрашиваемых одним пользователем, самые
популярные страницы нашего сайта,
страницы, с которых пользователи приходят на наш сайт, динамика визитов, операционные системы
и броузеры пользователей.
Сам скрипт counter, который вносит в таблицу hit новую запись об очередном открытии
нашей страницы, очень прост. Но он отличается от CGI-скриптов, рассмотренных ранее тем, что
выдает прозрачный GIF-файл размером 1х1 пиксел. Все счетчики устроены по такому принципу, т.к.
единственная возможность вызвать CGI-скрипт одновременно с загрузкой HTML-страницы - это
вызвать его в команде img.
/*
* (c) Copyright 1995-2000, Igor Tarasov
* http://itsoft.ru
* FidoNet: 2:5020/370.2 620.20 1103.5
* email: igor@itsoft.ru itarasov@rtuis.miem.edu.ru
* Phone: (095)916-89-51 916-89-63
*/
#include <stdio.h>
#include <mysql/mysql.h>
#include <itcgi.h>
int main()
{
MYSQL* pDB;
LString* sref = CreateString();
LString* pref = CreateString();
LString* spage = CreateString();
LString* ppage = CreateString();
LString* id = CreateString();
LString* ref = CreateString();
LString* browser = CreateString();
LString* version = CreateString();
LString* cookie = CreateString();
LString* frame = CreateString();
LString* java = CreateString();
LString* x = CreateString();
LString* y = CreateString();
LString* depth = CreateString();
LString* js = CreateString();
LString* os = CreateString();
char str[4096];
pDB = mysql_init(NULL);
if(!pDB)
{
printError(mysql_error(pDB));
return -1;
}
//получаем значения CGI-параметров,
//сформированных javascript'ом, приведенным выше
GetParamByName("id", id);
GetParamByName("r", ref);
GetParamByName("n", browser);
GetParamByName("v", version);
GetParamByName("c", cookie);
GetParamByName("f", frame);
GetParamByName("j", java);
GetParamByName("x", x);
GetParamByName("y", y);
GetParamByName("d", depth);
GetParamByName("js", js);
GetParamByName("o", os);
//соединяемся с базой
if( !mysql_real_connect(pDB, NULL, "counter", "хххххх", "counter", 0, NULL, 0) )
{
printError("mysql_real_connect: %s\n", mysql_error(pDB));
goto LABEL_END;
}
//получаем адрес сайта, на который пришел пользователь
//эти адреса будут различаться в случае, если ваш счетчик
//установлен на несколько ваших веб-сайтов
GetServer(getenv("HTTP_REFERER"), spage);
//получаем адрес страницы сайта, на которую пришел пользователь
GetPage(getenv("HTTP_REFERER"), ppage);
//получаем адрес сайта, с которого пришел пользователь
GetServer(*ref, sref);
//получаем адрес страницы сайта, с которой пришел пользователь
GetPage(*ref, pref);
//формируем строку SQL-запроса
//обратите внимание, что мы используем функцию snprintf
//застраховавшись от переполнения буфера
snprintf(str, 4096, "INSERT INTO hit ( owner_id, shref, href, browser, version, \
cookie, frame, java, x, y, depth, js, os, ip, spage, page, it_date) VALUES (\
'%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', \
'%s', '%s', '%s', '%s', NOW())",
*id, *sref, *pref, *browser, *version, *cookie, *frame, *java, *x, *y, *depth,
*js, *os, getenv("REMOTE_ADDR"), *spage, *ppage);
//вставляем новую запись в таблицу hit
if( mysql_query(pDB, str) )
{
printError("mysql_query: SQL=%s<br> %s\n", str, mysql_error(pDB));
goto LABEL_END;
}
//выдаем прозрачный GIF размером 1х1 пиксел
printf("Content-type: image/gif\n\n");
fwrite("GIF89a ? яяя !щ , @D ;", 1, 43, stdout);
LABEL_END:
//закрываем соединение с базой
mysql_close(pDB);
//освобождаем память
DeleteString(sref);
DeleteString(pref);
DeleteString(spage);
DeleteString(ppage);
DeleteString(id);
DeleteString(ref);
DeleteString(browser);
DeleteString(version);
DeleteString(cookie);
DeleteString(frame);
DeleteString(java);
DeleteString(x);
DeleteString(y);
DeleteString(depth);
DeleteString(js);
DeleteString(os);
return 0;
}
******Makefile***********
all: counter
counter: counter.c itcgi.a
gcc counter.c -L/usr/local/lib/mysql \
-L/usr/local/lib -I/usr/local/include \
-o counter -lmysqlclient /usr/lib/itcgi.a -Wall -O3
strip counter
Создайте базу данных counter, а в ней таблицу hit, приведенную выше. Соберите данный
CGI-скрипт и разместите код счетчика на ваших страницах.
Далее мы напишем программу построения отчетов.
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>
#include <itcgi.h>
int main()
{
MYSQL* pDB;
MYSQL_RES* res;
MYSQL_ROW row;
//переменные для хранения дня, за который строится отчет, и запроса
LString* day = CreateString();
LString* sql_query = CreateString();
pDB = mysql_init(NULL);
if(!pDB)
{
printError("Внимание! Ошибка!!!", mysql_error(pDB));
return -1;
}
if( !mysql_real_connect(pDB, NULL, "counter", "xxxx", "counter", 0, NULL, 0) )
{
printError("Внимание! Ошибка!!!", "mysql_real_connect: %s\n", mysql_error(pDB));
goto LABEL_END;
}
//выдаем HTTP-заголовок
printf("Content-type: text/html; charset=windows-1251\n\n");
//получаем день
GetParamByName("day", day);
if(!strlen(*day))
{
//если из CGI-параметров день не удалось получить,
//берем текущую дату
//CURDATE() вернет дату в виде 2002-01-08, т.е. 8 января 2002 года
LString_Format(sql_query, "SELECT CURDATE()");
mysql_query(pDB, *sql_query);
res = mysql_store_result(pDB);
row = mysql_fetch_row(res);
LString_SetString(day, row[0]);
mysql_free_result(res);
}
//Создаем ссылки для навигации по дням.
//Этот код непосредственно к отчетам не имеет отношения,
//поэтому его комментировать не будем.
LString_Format(sql_query,
"SELECT DATE_SUB('%s', INTERVAL 1 DAY),
DATE_ADD('%s', INTERVAL 1 DAY)", *day, *day);
mysql_query(pDB, *sql_query);
res = mysql_store_result(pDB);
row = mysql_fetch_row(res);
printf("<table border=0 width=95%%><tr><td align=left> \
<a href=/common/report?day=%s>Предыдущий день</a> \
<td align=center> %s
<td align=right><a href=/common/report?day=%s>Следующий день</a></table>",
row[0], *day, row[1]);
mysql_free_result(res);
//далее идут отчеты
//сначала печатаем заголовок
printf("<h4>Общее количество хостов и хитов</h4>");
//затем результат SQL-запроса
printTable(pDB, "SELECT COUNT(DISTINCT ip) as host, COUNT(*) as hit FROM hit");
printf("<h4>Динамика визитов по дням</h4>");
printTable(pDB, "SELECT count(distinct ip) as host, COUNT(*) as hit, \
DATE_FORMAT(it_date, '%Y-%m-%d') as date FROM hit \
GROUP BY date");
printf("<h4>Распределение хитов и хостов по часам</h4>");
LString_Format(sql_query, "SELECT count(distinct ip) as host, COUNT(*) as hit, \
DATE_FORMAT(it_date, '%%H') as hour FROM hit \
WHERE DATE_FORMAT(it_date, '%%Y-%%m-%%d')='%s' \
GROUP BY hour", *day);
printTable(pDB, *sql_query);
printf("<h4>Страницы - распределение хостов и хитов по страницам</h4>");
LString_Format(sql_query,
"SELECT COUNT(DISTINCT ip) as host, COUNT(*) as hit, \
CONCAT(spage,page) as url FROM hit \
WHERE DATE_FORMAT(it_date, '%%Y-%%m-%%d')='%s' \
GROUP BY url ORDER BY host DESC, hit DESC LIMIT 0,20", *day);
printTable(pDB, *sql_query);
printf("<h4>Страницы - распределение по доменным именам</h4>");
LString_Format(sql_query,
"SELECT COUNT(DISTINCT ip) as host, COUNT(*) as hit, spage FROM hit \
WHERE DATE_FORMAT(it_date, '%%Y-%%m-%%d')='%s' \
GROUP BY spage ORDER BY host DESC, hit DESC LIMIT 0,20", *day);
printTable(pDB, *sql_query);
printf("<h4>Ссылки - распределение по страницам</h4>");
LString_Format(sql_query, "SELECT COUNT(*) as q, shref, href FROM hit \
WHERE DATE_FORMAT(it_date, '%%Y-%%m-%%d')='%s' \
GROUP BY shref, href ORDER BY q DESC LIMIT 0,20", *day);
printTable(pDB, *sql_query);
printf("<h4>Ссылки - распределение по доменным именам</h4>");
LString_Format(sql_query, "SELECT COUNT(*) as q, shref FROM hit \
WHERE DATE_FORMAT(it_date, '%%Y-%%m-%%d')='%s' \
GROUP BY shref ORDER BY q DESC LIMIT 0,20", *day);
printTable(pDB, *sql_query);
printf("<h4>Распределение хитов по хостам</h4>");
LString_Format(sql_query, "CREATE TEMPORARY TABLE IF NOT EXISTS hh \
SELECT COUNT(*) as hit, ip FROM hit \
WHERE DATE_FORMAT(it_date, '%%Y-%%m-%%d')='%s' \
GROUP BY ip ORDER BY hit DESC", *day);
mysql_query(pDB, *sql_query);
printTable(pDB, "SELECT * FROM hh LIMIT 0,20");
printf("<h4>Среднее количество страниц, открываемых одним пользователем</h4>");
printTable(pDB, "SELECT AVG(hit) FROM hh");
printf("<h4>Распределение по операционным системам </h4>");
printTable(pDB, "SELECT COUNT(*) as q, os FROM hit \
GROUP BY os ORDER BY q DESC");
printf("<h4>Распределение по броузерам</h4>");
printTable(pDB, "SELECT COUNT(*) as q, browser FROM hit \
GROUP BY browser ORDER BY q DESC");
printf("<h4>Распределение по версиям броузеров</h4>");
printTable(pDB, "SELECT COUNT(*) as q, browser, version FROM hit \
GROUP BY browser, version ORDER BY q DESC ");
printf("<h4>Распределение по разрешению экрана</h4>");
printTable(pDB, "SELECT COUNT(*) as q, CONCAT(x, 'x', y) as res FROM hit \
GROUP BY res ORDER BY q DESC ");
printf("<h4>Распределение по количеству цветов</h4>");
printTable(pDB, "SELECT COUNT(*) as q, depth FROM hit
GROUP BY depth ORDER BY q DESC");
printf("<h4>Распределение по версиям javascript</h4>");
printTable(pDB, "SELECT COUNT(*), js FROM hit
GROUP BY js ORDER BY 1 DESC");
printf("<h4>Распределение по наличию java</h4>");
printTable(pDB, "SELECT count(*), java FROM hit
GROUP BY java ORDER BY 1 DESC");
printf("<h4>Распределение по наличию cookie</h4>");
printTable(pDB, "SELECT count(*), cookie FROM hit
GROUP BY cookie ORDER BY 1 DESC");
/*
printf("<h4></h4>");
printTable(pDB, "");
*/
LABEL_END:
mysql_close(pDB);
DeleteString(day);
DeleteString(sql_query);
return 0;
}
=========Makefile==========
all: report
report: report.c itcgi.a
gcc report.c -L/usr/local/lib/mysql \
-L/usr/local/lib -I/usr/local/include \
-o report -lmysqlclient /usr/lib/itcgi.a -Wall -O3
strip report
Имеет смысл обратить особое внимание на следующий код.
printf("<h4>Распределение хитов по хостам</h4>");
LString_Format(sql_query, "CREATE TEMPORARY TABLE IF NOT EXISTS hh \
SELECT COUNT(*) as hit, ip FROM hit \
WHERE DATE_FORMAT(it_date, '%%Y-%%m-%%d')='%s' \
GROUP BY ip ORDER BY hit DESC", *day);
mysql_query(pDB, *sql_query);
printTable(pDB, "SELECT * FROM hh LIMIT 0,20");
printf("<h4>Среднее количество страниц, открываемых одним пользователем</h4>");
printTable(pDB, "SELECT AVG(hit) FROM hh");
Во-первых, обратите внимание на то, как формируется строка SQL-запроса.
При использовании LString_Format вы застрахованы от переполнения буфера и имеете
возможность формировать строку с заранее неизвестным размером. Во-вторых, обратите внимание
на сам SQL-запрос. Мы сначала создаем временную таблицу hh, а затем выполняем для нее
два SQL-запроса. Необходимость использовать временную таблицу вызвана тем, что получить
одним запросом среднее количество страниц, открываемых одним пользователем, невозможно.
Мы сначала должны посчитать сколько страниц открыл каждый пользователь, а затем посчитать
среднее арифметическое. Временная таблица уничтожается автоматически, после завершения
соединения с базой либо же после явного вызова DROP TABLE. Помните об этом!
Результат работы CGI-скрипта report за 7 января 2002 года представлен ниже.
Общее количество хостов и хитов
Динамика визитов по дням
host | hit | date |
0 | 3 | (null) |
312 | 5016 | 2002-01-05 |
314 | 2529 | 2002-01-06 |
345 | 3241 | 2002-01-07 |
326 | 2701 | 2002-01-08 |
Распределение хитов и хостов по часам
host | hit | hour |
20 | 94 | 00 |
30 | 118 | 01 |
20 | 113 | 02 |
17 | 113 | 03 |
8 | 73 | 04 |
8 | 24 | 05 |
5 | 18 | 06 |
7 | 90 | 07 |
7 | 32 | 08 |
11 | 22 | 09 |
9 | 35 | 10 |
20 | 104 | 11 |
15 | 79 | 12 |
21 | 204 | 13 |
25 | 89 | 14 |
18 | 215 | 15 |
21 | 119 | 16 |
32 | 207 | 17 |
21 | 172 | 18 |
19 | 171 | 19 |
24 | 376 | 20 |
30 | 244 | 21 |
22 | 425 | 22 |
22 | 104 | 23 |
Страницы - распределение хостов и хитов по страницам
host | hit | url |
73 | 140 | www.opengl.org.ru/ |
50 | 61 | www.perl.org.ru/ |
37 | 85 | photo.itsoft.ru/ |
35 | 46 | www.perl.org.ru/download/software.html |
29 | 36 | www.opengl.org.ru/download/libraries.html |
27 | 42 | www.opengl.org.ru/download/ |
24 | 49 | www.perl.org.ru/documentation/ |
20 | 21 | www.opengl.org.ru/download/docs.html |
19 | 64 | www.opengl.org.ru/books/open_gl/ |
18 | 32 | www.perl.org.ru/cgi-bin/forum/UltraBoard.cgi |
18 | 25 | www.opengl.org.ru/cgi-bin/ultra/UltraBoard.cgi |
17 | 24 | www.opengl.org.ru/download/examples.html |
17 | 19 | www.opengl.org.ru/download/programs.html |
16 | 57 | www.opengl.org.ru/cgi-bin/ultra/UltraBoard.cgi?action=Headlines&BID=1&SID= |
16 | 35 | www.opengl.org.ru/books/open_gl/index.html |
15 | 17 | www.opengl.org.ru/docs/ |
14 | 17 | www.opengl.org.ru/books/open_gl/chapter1.1.html |
12 | 13 | www.opengl.org.ru/index.html |
11 | 13 | www.opengl.org.ru/download/libs_html/opengl_st1.html |
10 | 28 | photo.itsoft.ru/l1.html?cn=human&rus=ЧЕЛОВЕК |
Страницы - распределение по доменным именам
host | hit | spage |
138 | 996 | www.opengl.org.ru |
88 | 395 | www.perl.org.ru |
41 | 1587 | photo.itsoft.ru |
26 | 47 | nit.itsoft.ru |
24 | 78 | itsoft.ru |
10 | 32 | futuris.itsoft.ru |
10 | 12 | gb.itsoft.ru |
9 | 12 | mobile.org.ru |
8 | 30 | learning.itsoft.ru |
6 | 20 | linux.itsoft.ru |
4 | 4 | www.yandex.ru |
4 | 4 | members.itsoft.ru |
3 | 17 | miem.itsoft.ru |
1 | 5 | world.altavista.com |
1 | 2 | www.ya.ru |
Ссылки - распределение по страницам
q | shref | href |
382 | | |
166 | www.opengl.org.ru | / |
105 | photo.itsoft.ru | / |
72 | www.opengl.org.ru | /books/open_gl/ |
70 | www.perl.org.ru | / |
52 | www.opengl.org.ru | /cgi-bin/ultra/UltraBoard.cgi |
49 | www.opengl.org.ru | /books/open_gl/index.html |
45 | www.perl.org.ru | /documentation/ |
37 | itsoft.ru | / |
31 | photo.itsoft.ru | /l1.html?cn=human&rus=а427а415а41Bа41Eа412а415а41A |
30 | www.opengl.org.ru | /download/ |
24 | www.yandex.ru | /yandsearch?text=opengl |
19 | photo.itsoft.ru | /l1.html?cn=animals&rus=а416а418а412а41Eа422а41Dа42Bа415 |
19 | photo.itsoft.ru | /l1.html?cn=other&rus=а414а420а423а413а41Eа415 |
19 | www.opengl.org.ru | /docs/pg/index.html |
18 | www.perl.org.ru | /cgi-bin/forum/UltraBoard.cgi |
18 | www.opengl.org.ru | /docs/ |
16 | photo.itsoft.ru | /l1.html?cn=landscape&rus=а41Bа410а41Dа414а428а410а424а422а42B |
16 | www.opengl.org.ru | /download/examples.html |
15 | www.opengl.org.ru | /cgi-bin/ultra/UltraBoard.cgi?action=Headlines&BID=1&SID= |
Ссылки - распределение по доменным именам
q | shref |
1515 | photo.itsoft.ru |
644 | www.opengl.org.ru |
382 | |
262 | www.perl.org.ru |
121 | www.yandex.ru |
82 | itsoft.ru |
24 | www.google.com |
20 | nit.itsoft.ru |
15 | www.ya.ru |
14 | learning.itsoft.ru |
14 | catalog.aport.ru |
14 | yandex.ru |
13 | futuris.itsoft.ru |
11 | miem.itsoft.ru |
10 | search.rambler.ru |
10 | ya.ru |
8 | linux.itsoft.ru |
8 | list.mail.ru |
7 | vbstreets.ru |
5 | world.altavista.com |
Распределение хитов по хостам
hit | ip |
477 | 194.67.67.194 |
319 | 195.42.120.42 |
140 | 159.148.175.76 |
102 | 195.62.129.22 |
96 | 212.199.23.199 |
60 | 195.250.65.226 |
58 | 217.70.107.198 |
50 | 212.38.113.239 |
47 | 195.151.42.2 |
46 | 62.118.128.1 |
44 | 195.13.227.39 |
43 | 194.27.68.220 |
42 | 213.247.140.169 |
38 | 194.190.217.17 |
37 | 195.239.77.249 |
32 | 128.112.71.29 |
31 | 212.49.3.180 |
30 | 193.193.211.37 |
30 | 195.22.231.224 |
29 | 195.34.32.11 |
Среднее количество страниц, открываемых одним пользователем
Распределение по операционным системам
q | os |
13301 | Win32 |
66 | LinuxELF2.2 |
63 | X11 |
44 | Linux i686 |
5 | Linux |
4 | MacPPC |
4 | |
3 | (null) |
2 | SunOS5.5.1 |
1 | IRIX6.5 |
Распределение по броузерам
q | browser |
12948 | Microsoft Internet Explorer |
401 | Netscape |
74 | Opera |
63 | Konqueror |
3 | (null) |
3 | Microsoft |
1 | |
Распределение по версиям броузеров
q | browser | version |
4482 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 5.5; Windo |
3504 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 5.0; Windo |
3232 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 5.01; Wind |
1380 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 6.0; Windo |
261 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 4.01; Wind |
88 | Netscape | 4.04 [en] (Win95; I) |
55 | Netscape | 4.76 [en] (Win98; U) |
54 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 6.0b; Wind |
50 | Netscape | 4.76 [ru] (X11; U; Linux 2.2.18- |
44 | Netscape | 5.0 (X11; en-US) |
33 | Netscape | 5.0 (Windows; en-US) |
32 | Opera | 5.12 (Windows 98; U) |
30 | Konqueror | 5.0 (compatible; Konqueror/2.1; |
26 | Konqueror | 5.0 (compatible; Konqueror/2.1.1 |
26 | Netscape | 4.77 [en] (Windows NT 5.0; U) |
24 | Netscape | 4.7 [en] (Win98; I) |
23 | Opera | 6.0 (Windows 98; U) |
15 | Opera | 6.0 (Windows 2000; U) |
15 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 5.0; MSNIA |
15 | Netscape | 4.7 [ru] (Win95; I) |
12 | Netscape | 4.04 [en] (Win95; I ;Nav) |
10 | Netscape | 5.0 (Windows 98; U) |
8 | Netscape | 4.61 [en] (Win98; I) |
7 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 4.0; Windo |
7 | Konqueror | 5.0 (compatible; Konqueror/2.2-1 |
6 | Netscape | 4.75 [en] (X11; U; Linux 2.2.16- |
6 | Netscape | 4.74 [en] (Win98; U) |
5 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 5.0; Linux |
4 | Opera | 6.0 (Windows ME; U) |
4 | Netscape | 4.77 [en] (X11; U; Linux 2.2.12 |
4 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 5.0; AOL 6 |
3 | Netscape | 4.72 [en] (X11; U; Linux 2.2.14- |
3 | Netscape | 4.78 [en] (Win98; U) |
3 | Netscape | 4.76 [en] (X11; U; Linux 2.4.2-2 |
3 | Microsoft | |
3 | (null) | (null) |
2 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 5.0; Macin |
2 | Netscape | 4.73 [en] (X11; I; SunOS 5.8 sun |
2 | Netscape | 4.6 [en] (WinNT; I) |
2 | Microsoft Internet Explorer | 4.0 (compatible; MSIE 5.01; AOL |
1 | Netscape | 4.7 [en] (Win95; I) |
1 | Netscape | 4.76 [en]C-CCK-MCD QXW03200 (Wi |
1 | Netscape | 4.75 [en] (X11; U; IRIX64 6.5 IP |
1 | | |
1 | Netscape | 4.72 [en] (WinNT; I) |
1 | Netscape | 4.75C-CCK-MCD {C-UDP; EBM-APPLE} |
1 | Netscape | 4.78 (Macintosh; U; PPC) |
1 | Netscape | 4.7 [ru] (WinNT; I) |
Распределение по разрешению экрана
q | res |
6468 | 800x600 |
5519 | 1024x768 |
812 | 1152x864 |
434 | 1280x1024 |
78 | 640x480 |
76 | 960x720 |
43 | 1280x960 |
31 | 1600x1200 |
8 | 720x480 |
7 | 1280x768 |
6 | 1400x1050 |
4 | 0x0 |
3 | (null) |
2 | 1152x900 |
1 | 512x384 |
1 | 2048x1120 |
Распределение по количеству цветов
q | depth |
5369 | 16 |
4717 | 32 |
3309 | 24 |
76 | 8 |
9 | 1 |
5 | 0 |
5 | 4 |
3 | (null) |
Распределение по версиям javascript
COUNT(*) | js |
13118 | 13 |
365 | 12 |
4 | |
3 | 10 |
3 | 0 |
Распределение по наличию java
count(*) | java |
13274 | 1 |
215 | 0 |
4 | |
Распределение по наличию cookie
count(*) | cookie |
13366 | 1 |
121 | 0 |
6 | |
На основании полученной статистики любопытно отметить, что абсолютное большинство
пользователей наших сайтов работает на платформе Win32 в броузере Internet Explorer,
имеют разрешение экрана не меньше 800х600, а каждый второй имеет не меньше 1024х768,
количество цветов не менее 65 тысяч и у них поддерживаются технологии Java, JavaScript и
Cookie.