Statistika přístupů v PHP – vyhledávací fráze

13. března 2004

V tomto článku navážeme na předchozí analýzu, v níž jsme určovali, odkud přicházejí návštěvníci našich stránek. Ukážeme si, jak zjistit, které fráze používají návštěvníci ve vyhledávačích, jako je Seznam nebo Google, a jak správně ošetřit jejich různá kódování.

Hotovou aplikaci si můžete prohlédnout a vyzkoušet. V ukázkové verzi se provádí statistika přístupů stránek http://www.czechia.cz/help/.

Na úvod by se hodilo říci, co je vlastně ta „vyhledávací fráze“. Jedná se o text, který uživatel zadal v některém vyhledávači. Tento vyhledávač mu našel několik odkazů odpovídajících danému textu, které pak většinou bývají zobrazeny na stránce, jejíž URL má tvar http://vyhledavac.cz/search.php?parametr=vyhledavaci_fraze. Mezi nalezenými odkazy se může objevit i odkaz na naši stránku. Uživatel na něj klikne a dostanete se tak na naše stránky, přičemž v hlavičce Referer je uložena výše popsaná stránka toho kterého vyhledávače. Hlavičku Referer jsme využili již při vytváření statistiky serverů, ze kterých návštěvníci přicházejí a právě z ní se dá vyčíst i použitá vyhledávací fráze.

Vytvořením statistiky vyhledávacích frází si můžeme ověřit například, zda uživatelé najdou na našich to, co hledají, zda-li se nedostávají na naše stránky nějakým omylem a podobně. Úplné pochopení celé problematiky vyžaduje znalost předchozího článku. Připomenu proto jen nejdůležitější věc – hlavička Referer je uložena v proměnné $_GET['referer'].

Část zjišťující, zda uživatel přišel z vyhledávače a použil přitom nějakou frázi, umístíme do poslední větve podmínky zjišťující odkud návštěvník přišel. Úvodní část této větve, kterou znáte z předchozího článku, provádí obecnou statistiku příchodů z cizích stránek.

Ještě předtím ale musíme vyřešit problém s kódováním vyhledávacích frází. Obvykle se jedná o kódování ISO-8859-2, Windows-1250 a UTF-8. Ke vzájemnému převodu mezi těmito sadami můžeme použít výbornou knihovnu AutoCzech od pana Semeckého. Obsahuje sice pár drobných chyb v kódování UTF-8, můžete si ale stáhnout i aktualizovanou verzi přímo z Intervalu.

Mohlo by se zdát, že nyní je převod úspěšně vyřešen. Problémy však teprve přijdou. Zkuste si v Internet Exploreru vyhledat na Seznamu nebo iDNES třeba frázi „Tomášek Novák“ – v URL se objeví znaky, které tam nemají co dělat. V tom okamžiku přichází na řadu javascriptové funkce escape() v kódu zajišťujícím vkládání měřícího obrázku (counter.php). Zpětné dekódování pomocí PHP funkce urldecode() se však kvůli odlišnému chování funkce escape() neprovede úplně správně. V čem je rozdíl? Zatímco urlencode() a urldecode() používají pro všechny znaky „%“ a dvě šestnáctkové číslice, escape() kóduje některé znaky sekvencí „%u“ + čtyři šestnáctkové číslice. Více informací o této problematice najdete v odkazech pod článkem.

Pokud toto víme, stačí znaky, které jsou kódovány čtyřmi šestnáctkovými číslicemi, převést zpět. Použijeme dvě pole a funkci str_replace(). Ostatní znaky dekódujeme pomocí urldecode() a výsledek převedeme do kódování Windows-1250.

// REFERER – odkud prisel navstevnik
$referer = 2; // predpokladame prechod v ramci serveru
if(isset($_GET[‚referer‘])) {
$escape = array (‚%u010C‘, ‚%u010E‘, ‚%u011A‘, ‚%u0147‘, ‚%u0158‘, ‚%u0160‘, ‚%u0164‘, ‚%u016E‘, ‚%u017D‘, ‚%u010D‘, ‚%u010F‘, ‚%u011B‘, ‚%u0148‘, ‚%u0159‘, ‚%u0161‘, ‚%u0165‘, ‚%u016F‘, ‚%u017E‘, ‚%u0105‘, ‚%u013E‘);
$unescape = array (‚Č‘, ‚Ď‘, ‚Ě‘, ‚Ň‘, ‚Ř‘, ‚Š‘, ‚Ť‘, ‚Ů‘, ‚Ž‘, ‚č‘, ‚ď‘, ‚ě‘, ‚ň‘, ‚ř‘, ‚š‘, ‚ť‘, ‚ů‘, ‚ž‘, ‚š‘, ‚ž‘);
  // rozkoduje URL a prevede na mala pismena
  $http_referer = str_replace($escape, $unescape, urldecode(addslashes($_GET[‚referer‘])) )
  $http_referer = strtolower( autoczech($http_referer, ‚win‘) );
  if ($http_referer == “) { // prime volani
    $referer = 1;
  
  } elseif (eregi(no_Referer, $http_referer)) { // prechod v ramci serveru
    $referer = 2;
  } else { // navstevnik prisel z cizich stranek
    . . .
    . . .
    // VYHLEDAVACE – jaka fraze byla pouzita pri vyhledavani
    . . .
    . . .

Databázová struktura

Celá statistika vyhledávacích frází (přístupů z vyhledávačů) bude úplně oddělena od základní databázové tabulky access a bude tvořena celkem třemi tabulkami, což dobře znázorňuje následující schéma. Nejdůležitější je tabulka searched obsahující datum přístupu z určitého vyhledávače a použitou frázi. Protože vyhledávací fráze i vyhledávače se budou opakovat, bude lepší tyto údaje ukládat do tabulky searched jako cizí klíče z tabulek searchengine a searchtext.

Schéma použité databáze (náhled)
Schéma použité databáze (plná velikost, cca 10 kB)

Tabulky vytvoříme pomocí těchto SQL dotazů:

CREATE TABLE searched (
  id int NOT NULL auto_increment,
  search_date datetime NOT NULL,
  server int NOT NULL,
  query int NOT NULL,
  PRIMARY KEY (id)
)

  • id – unikátní označení každého přístupu s použitím vyhledávací fráze (primární klíč)
  • search_date – datum a čas tohoto přístupu
  • server – použitý vyhledávač
  • query – použitá fráze

CREATE TABLE searchengine (
  id int NOT NULL auto_increment,
  server varchar(50) NOT NULL,
  variable varchar(20) NOT NULL,
  PRIMARY KEY (id)
)

  • id – unikátní označení každého vyhledávače (primární klíč)
  • server – doménová adresa vyhledávače
  • variable – parametr, který server používá pro vyhledávaní (obsahuje vyhledávací frázi)

CREATE TABLE searchtext (
  id int NOT NULL auto_increment,
  query varchar(150) NOT NULL,
  PRIMARY KEY (id)
)

  • id – unikátní označení každé vyhledávací fráze (primární klíč)
  • query – text fráze

Abychom mohli něco zjistit, musíme mít v tabulce searchengine nějaká data, to jest informace o nejvýznamnějších vyhledávačích. Nejdůležitější je položka variable. Možná ještě někomu není úplně jasné, co vlastně obsahuje. Uvedu proto jeden příklad. Máme odkaz http://search.seznam.cz/search.cgi?w=biologie. Vyhledávací fráze „biologie“ je obsažena v parametru „w“ a právě ten uložíme do položky variable. Seznam nejdůležitějších českých a zahraničních vyhledávačů přináší tato tabulka (searchengine):

id server variable
1 seznam.cz w
2 centrum.cz q
3 atlas.cz q
4 google.com q
5 webfast.cz q
6 idnes.cz q
7 redbox.cz qs
8 quick.cz ftxt_query
9 volny.cz search
10 tiscali.cz query
11 zoznam.sk s
12 altavista.com q
13 yahoo.com p
14 morfeo.cz q
15 jyxo.cz s
16 caramba.cz Text
17 katedrala.cz KeyWords
18 toplist.cz search
19 zona.cz TERMS
20 dmoz.org search
21 msn.com q
22 zoohoo.cz q
23 icq.com q
24 yo.cz q
25 ask.com query
26 aol.com query
27 hotbot.com query
28 lycos.com query
29 overture.com Keywords
30 mamma.com query

Teorii máme za sebou, nyní přichází na řadu zpracování celé úlohy. Z předchozího článku víme, jak z URL zjistit doménovou adresu. Z doménové části odkazu $_GET['http_referer'] (tedy $url['host']) musíme zjistit doménu druhé a první úrovně, abychom ji mohli porovnat se záznamy v tabulce searchengine a případně pokračovat dál. Pokud byl nějaký záznam nalezen, znamená to, že uživatel přichází z vyhledávače a můžeme se tedy pustit do zjištění použité vyhledávací fráze. Část odkazu za „?“ (= dotaz), kterou máme po zpracování odkazu funkcí url_parse v poli s indexem query, obsahuje kromě dalších parametrů i námi hledaný parametr s vyhledávací frází.

Po rozdělení na jednotlivé parametry oddělené znakem „&“ zjistíme pomocí jednoduchého cyklu obsah daného parametru ($result['variable']), což je ona vyhledávací fráze. Celý parametr nejprve rozdělíme na části oddělené „=“. V první části je pak název parametru, v druhé jeho obsah (= vyhledávací fráze). Vyhledávací frázi si na závěr uložíme do proměnné $searchtext.

// VYHLEDAVACE – jaka fraze byla pouzita pri vyhledavani
$explode = explode(‚.‘, $url[‚host‘]); // rozdeli adresu serveru na jednotlive casti
$host_domain = $explode[count($explode) – 2] . ‚.‘ . $explode[count($explode) – 1]; // domena 2. urovne
// jedna se o vyhledavac?
$query = mysql_query(„SELECT * FROM searchengine WHERE server = ‚$host_domain'“);
if($result = mysql_fetch_array($query)) {
  // zjistime pouzitou frazi – pres parametr, ktery vyhledavac pouziva
  $variables = explode(‚&‘, $url[‚query‘]);
  for($i = 0;$i < count($variables);$i++) {
    $explode = explode(‚=‘, $variables[$i]);
    if($explode[0] == $result[‚variable‘]) {
      $searchtext = $explode[1]; // fraze pouzita pri vyhledavani
      break;
    }
  }

Někdy se může stát, že uživatel sice přijde například ze Seznamu, ale nepoužije vyhledávání, nýbrž katalog. V takovém případě se žádná fráze zjistit nedá, takže musíme uvést následující podmínku. Za ní nejprve pomocí známých postupů uložíme do tabulky searchtext vyhledávací frázi a následně do tabulky searched veškeré informace o daném přístupu z vyhledávače.

  // pokud se podarilo zjistit frazi, zapiseme vse do databaze
  if($searchtext != “) {
    $server = $result[‚id‘];
    // je fraze v databazi ? (pokud ne, pridame ji)
    $query = mysql_query(„SELECT id FROM searchtext WHERE query = ‚$searchtext'“);
    if ($result = mysql_fetch_array($query)) {
      $search_id = $result[‚id‘];
    } else {
      $query = mysql_query(„INSERT INTO searchtext VALUES (“, ‚$searchtext‘)“);
      $search_id = mysql_insert_id();
    }
    $query = mysql_query(„INSERT INTO searched VALUES (“, ‚$date‘, ‚$server‘, ‚$search_id‘)“);
  }
}

Vyhodnocení

Statistiku použitých vyhledávacích frází za dané období vypíšeme do jedné tabulky. Na prvním řádku bude celkový počet přístupů s použitím vyhledávací fráze. Do dalších řádků vložíme počet přístupů z jednotlivých vyhledávačů. Pod každým vyhledávačem pak bude seznam vyhledávacích frází, počet použití dané fráze a její podíl na celkovém počtu.

// VYHLEDAVACI FRAZE
// celkovy pocet pristupu ze vsech vyhledavacu za dane obdobi
$query = mysql_query(„SELECT count(id) FROM searched WHERE $sql_search_date“);
$result = mysql_fetch_array($query);
$count_search = $result[‚count(id)‘];
if($count_search != 0) {
  echo ‚<h2>Fráze použité při vyhledávání</h2>‘;
  echo ‚<table width=“680″ cellspacing=“0″>‘;
  echo ‚<tr><th>Vyhledávač (fráze)</th><th>Počet</th><th class=“width1″>Podíl</th></tr>‘;
  echo ‚<tr><td>Celkem</td><td>‘ . $count_search . ‚</td><td> </td></tr>‘;

V prvním SQL dotazu, který zjišťuje zastoupení jednotlivých vyhledávačů, spojíme tabulky searchengine a searched. V druhém SQL dotazu, zjišťujícím fráze použité na jednotlivých vyhledávačích, spojíme tabulky searchtext a searched, přičemž nesmíme zapomenout na podmínku WHERE searched.server = '$id', kde $id je označení právě zpracovávaného serveru, které získáme z prvního dotazu. Myslím, že SQL dotazy žádný další komentář nepotřebují, vztahy mezi tabulkami dobře znázorňuje výše uvedené schéma. Další postup, tedy výpočet šířky obrázku a podílu, byl podrobně komentován v článku popisujícím metodiku dtekce operačního systému.

// vybirame vyhledavace podle jejich zastoupeni
  $query = mysql_query(„SELECT searchengine.id AS id, searchengine.server AS server, count(searchengine.id) AS count_it FROM searched JOIN searchengine ON (searchengine.id = searched.server) WHERE $sql_search_date GROUP BY searchengine.id ORDER BY count_it DESC“);
  $max = mysql_result($query, 0, ‚count_it‘); // pocet pristupu z nejvíce zastoupeneho vyhledavace
  $move = mysql_data_seek($query, 0); // presuneme se znovu na zacatek
  while($result = mysql_fetch_array($query)) {
    $width = round($result[‚count_it‘]/$max*380); // sirka obrazku znazornujiciho podil
    $rate = sprintf(‚%.2f‘, $result[‚count_it‘]/($count_search/100)); // podil v procentech
    echo ‚<tr class=“tableheader“><td>‘ . $result[‚server‘] . ‚</td><td>‘ . $result[‚count_it‘] . ‚</td><td><img src=“1.gif“ width=“‚ . $width . ‚“ height=“8″ alt=““ /> ‚ . $rate . ‚ %</td></tr>‘ . „\n“;
    // vybirame vyhledavací fraze u daneho vyhledavace (podle poctu)
    $id = $result[‚id‘]; // id vyhledavace
    $query2 = mysql_query(„SELECT searchtext.query AS query, count(searchtext.id) AS count_it FROM searched JOIN searchtext ON (searched.query = searchtext.id) WHERE searched.server = ‚$id‘ AND $sql_search_date GROUP BY searchtext.id ORDER BY count_it DESC“);
    while($result = mysql_fetch_array($query2)) {
      $rate = sprintf(‚%.2f‘, $result[‚count_it‘]/($count_search/100)); // podil v procentech
      $width = round($result[‚count_it‘]/$max*380); // sirka obrazku znazornujiciho podil
      echo ‚<tr><td>‘ . $result[‚query‘] . ‚</td><td>‘ . $result[‚count_it‘] . ‚</td><td><img src=“1.gif“ width=“‚ . $width . ‚“ height=“8″ alt=““ /> ‚ . $rate . ‚ %</td></tr>‘ . „\n“;
    }
  }
  echo „</table>\n\n“;
}

Odkazy, zdroje

Pozn. red.: Tento článek vyšel poprvé 8. 7. 2002. Původní verze článku a k němu vedené diskuse jsou vám k dispozici v ZIP archivech.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *