Компонент вычисления PageRank и Yandex тИЦ для сервиса SEO анализа
Продолжаем писать сервис SEO анализа. В первой части мы спланировали приложение и отправку\приём данных через AJAX с использованием библиотеки PHPLiveX, в этой добавим компоненты для определения тИЦ и PageRank, Alexa Rank.
Архитектура обработчика ранков
Для реализации спланируем затык на вырост, поэтому приложение будет частично реализовано через OОП. Этот метод подойдёт больше и будет более удобен т.к. некоторые элементы конфигурировать (например Yandex XML) мы будем перед выполнение кода — позволит менять логику запросов без вмешательства в функциональность.
Для примера я привожу свой код processor.php. Вы можете его при желании подправить под себя.
extract($_GET); if (!empty($url)) { $url = preg_replace("/[^\x20-\xFF]/","",@strval($url)); $url = str_replace("http://","",$url); $url = preg_replace ("/^[^a-zA-ZА-Яа-я0-9\s]*$/","",$url); $url = strtolower($url); $url = str_replace("/","",$url); $url = htmlspecialchars($url); $processor = new summary_index_processor(); // Ranks >>> $yaCY = $processor->getCY($url); $PageRank = getPR($url); $AlexaRank = $processor->AlexaRank($url); $render = "<h3>Анализ сайта →<span style=float:right><img src=http://favicon.yandex.net/favicon/".$url." /><a href=http://".$url." target=_blank rel=nofollow>".$url."⇒</a></span></h3>"; $render.= '<table width=500px style=border: 1px solid #999>'; $render.= ' <tr class=odd> <td>Яндекс тИЦ: <b>'.$yaCY.'</b></td> <td>Google PR: <b>'.$PageRank.'</b></td> <td>Alexa Rank: <b>'.$AlexaRank.'</b></td> </tr></table>'; echo $render; } else { echo "<center><b style=color:#f00000>введите адрес или домен!</b></center>"; }
Приняли переменную, обработали для дальнейшего использования. В случае отсутствия переменной предупредили пользователя.
Теперь подробнее. Сразу создадим класс для обработки большинства функций.
$processor = new summary_index_processor();
Чтобы получить результат работы изолированных функций будем использовать такой синтаксис:
$yaCY = $processor->getCY($url);
Далее нужно написать сам класс c двумя публичными функциями(на вырост).
class summary_index_processor { /* YANDEX CY */ public function getCY($url){ $uri = "http://bar-navig.yandex.ru/u?ver=2&url=".urlencode("http://".$url)."&show=1"; $fd = @fopen($uri, "r"); if ($fd) { while ($buffer = fgets($fd, 4096)) $haystack.=$buffer; fclose($fd); preg_match("/<tcy rang=\"(.*)\" value=\"(.*)\"\/>/isU", $haystack,$cy); return $cy[2]; } else return 0; } /* ALEXA */ public function AlexaRank($site_url){ $content = file_get_contents('http://data.alexa.com/data?cli=10&dat=snbamz&url='.urlencode($site_url)); preg_match('/\<popularity url\="(.*?)" TEXT\="([0-9]+)"\/\>/si', $content, $alexa); return $alexa[2]; } }
Функции при обработке вернут значение тИЦ полученное с Яндекс.Bar, при его отсутствии вернёт 0 и Global Alexa Rank.
C классом закончили. Далее сделаем логику для вычисления PR. Пока вне класса.
function strToNum($str, $check, $magic){ $int32Unit = 4294967296; // 2^32 $length = strlen($str); for ($i = 0; $i < $length; $i++) { $check *= $magic; if ($check >= $int32Unit) { $check = ($check - $int32Unit * (int) ($check / $int32Unit)); //if the check less than -2^31 $check = ($check < -2147483648) ? ($check + $int32Unit) : $check; } $check += ord($str{$i}); } return $check; } // hash url get function hashUrl($string){ $check1 = strToNum($string, 0x1505, 0x21); $check2 = strToNum($string, 0, 0x1003F); $check1 >>= 2; $check1 = (($check1 >> 4) & 0x3FFFFC0 ) | ($check1 & 0x3F); $check1 = (($check1 >> 4) & 0x3FFC00 ) | ($check1 & 0x3FF); $check1 = (($check1 >> 4) & 0x3C000 ) | ($check1 & 0x3FFF); $T1 = (((($check1 & 0x3C0) << 4) | ($check1 & 0x3C)) <<2 ) | ($check2 & 0xF0F ); $T2 = (((($check1 & 0xFFFFC000) << 4) | ($check1 & 0x3C00)) << 0xA) | ($check2 & 0xF0F0000 ); return ($T1 | $T2); } // checksumm processor function checkHash($hashNum){ $checkByte = 0; $flag = 0; $hashStr = sprintf('%u', $hashNum) ; $length = strlen($hashStr); for ($i = $length - 1; $i >= 0; $i --) { $re = $hashStr{$i}; if (1 === ($flag % 2)) { $re += $re; $re = (int)($re / 10) + ($re % 10); } $checkByte += $re; $flag ++; } $checkByte %= 10; if (0 !== $checkByte) { $checkByte = 10 - $checkByte; if (1 === ($flag % 2) ) { if (1 === ($checkByte % 2)) { $checkByte += 9; } $checkByte >>= 1; } } return '7' . $checkByte . $hashStr; } // connect to google like a mozilla browser (: function getPR($url){ if ( ! preg_match('/^(http:\/\/)(.*)/i', $url)) { $url = 'http://' . $url; } $googlehost = 'toolbarqueries.google.com'; $googleua = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.6) Gecko/20060728 Firefox/1.5'; $ch = checkHash(hashUrl($url)); // socet connector impliment $fp = fsockopen($googlehost, 80, $errno, $errstr, 30); if ($fp) { $out = "GET /search?client=navclient-auto&ch=$ch&features=Rank&q=info:$url HTTP/1.1\r\n"; $out .= "User-Agent: $googleua\r\n"; $out .= "Host: $googlehost\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); while ( ! feof($fp)) { $data = fgets($fp, 128); $pos = strpos($data, "Rank_"); if($pos === false){} else{ fclose($fp); $pr = substr($data, $pos + 9); $pr = trim($pr); $pr = str_replace("\n",'',$pr); return $pr ? $pr : '0'; } } fclose($fp); } }
Четыре связанные функции вернут число PageRank.
Итоговый код процессора ранков
extract($_GET); if (!empty($url)) { $url = preg_replace("/[^\x20-\xFF]/","",@strval($url)); $url = str_replace("http://","",$url); $url = preg_replace ("/^[^a-zA-ZА-Яа-я0-9\s]*$/","",$url); $url = strtolower($url); $url = str_replace("/","",$url); $url = htmlspecialchars($url); $processor = new summary_index_processor(); // Ranks >>> $yaCY = $processor->getCY($url); $PageRank = getPR($url); $AlexaRank = $processor->AlexaRank($url); $render = "<h3>Анализ сайта →<span style=float:right><img src=http://favicon.yandex.net/favicon/".$url." /><a href=http://".$url." target=_blank rel=nofollow>".$url."⇒</a></span></h3>"; $render.= '<table width=500px style=border: 1px solid #999>'; $render.= ' <tr class=odd> <td>Яндекс тИЦ: <b>'.$yaCY.'</b></td> <td>Google PR: <b>'.$PageRank.'</b></td> <td>Alexa Rank: <b>'.$AlexaRank.'</b></td> </tr></table>'; echo $render; } else { echo "<center><b style=color:#f00000>введите адрес или домен!</b></center>"; } class summary_index_processor { /* YANDEX CY */ public function getCY($url){ $uri = "http://bar-navig.yandex.ru/u?ver=2&url=".urlencode("http://".$url)."&show=1"; $fd = @fopen($uri, "r"); if ($fd) { while ($buffer = fgets($fd, 4096)) $haystack.=$buffer; fclose($fd); preg_match("/<tcy rang=\"(.*)\" value=\"(.*)\"\/>/isU", $haystack,$cy); return $cy[2]; } else return 0; } /* ALEXA */ public function AlexaRank($site_url){ $content = file_get_contents('http://data.alexa.com/data?cli=10&dat=snbamz&url='.urlencode($site_url)); preg_match('/\<popularity url\="(.*?)" TEXT\="([0-9]+)"\/\>/si', $content, $alexa); return $alexa[2]; } } // <<< summary_index_processor function strToNum($str, $check, $magic){ $int32Unit = 4294967296; // 2^32 $length = strlen($str); for ($i = 0; $i < $length; $i++) { $check *= $magic; if ($check >= $int32Unit) { $check = ($check - $int32Unit * (int) ($check / $int32Unit)); //if the check less than -2^31 $check = ($check < -2147483648) ? ($check + $int32Unit) : $check; } $check += ord($str{$i}); } return $check; } // hash url get function hashUrl($string){ $check1 = strToNum($string, 0x1505, 0x21); $check2 = strToNum($string, 0, 0x1003F); $check1 >>= 2; $check1 = (($check1 >> 4) & 0x3FFFFC0 ) | ($check1 & 0x3F); $check1 = (($check1 >> 4) & 0x3FFC00 ) | ($check1 & 0x3FF); $check1 = (($check1 >> 4) & 0x3C000 ) | ($check1 & 0x3FFF); $T1 = (((($check1 & 0x3C0) << 4) | ($check1 & 0x3C)) <<2 ) | ($check2 & 0xF0F ); $T2 = (((($check1 & 0xFFFFC000) << 4) | ($check1 & 0x3C00)) << 0xA) | ($check2 & 0xF0F0000 ); return ($T1 | $T2); } // checksumm processor function checkHash($hashNum){ $checkByte = 0; $flag = 0; $hashStr = sprintf('%u', $hashNum) ; $length = strlen($hashStr); for ($i = $length - 1; $i >= 0; $i --) { $re = $hashStr{$i}; if (1 === ($flag % 2)) { $re += $re; $re = (int)($re / 10) + ($re % 10); } $checkByte += $re; $flag ++; } $checkByte %= 10; if (0 !== $checkByte) { $checkByte = 10 - $checkByte; if (1 === ($flag % 2) ) { if (1 === ($checkByte % 2)) { $checkByte += 9; } $checkByte >>= 1; } } return '7' . $checkByte . $hashStr; } // connect to google like a mozilla browser (: function getPR($url){ if ( ! preg_match('/^(http:\/\/)(.*)/i', $url)) { $url = 'http://' . $url; } $googlehost = 'toolbarqueries.google.com'; $googleua = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.6) Gecko/20060728 Firefox/1.5'; $ch = checkHash(hashUrl($url)); // socet connector impliment $fp = fsockopen($googlehost, 80, $errno, $errstr, 30); if ($fp) { $out = "GET /search?client=navclient-auto&ch=$ch&features=Rank&q=info:$url HTTP/1.1\r\n"; $out .= "User-Agent: $googleua\r\n"; $out .= "Host: $googlehost\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); while ( ! feof($fp)) { $data = fgets($fp, 128); $pos = strpos($data, "Rank_"); if($pos === false){} else{ fclose($fp); $pr = substr($data, $pos + 9); $pr = trim($pr); $pr = str_replace("\n",'',$pr); return $pr ? $pr : '0'; } } fclose($fp); } }
В следующий раз будем писать логику для проверки наличия в трастовых каталогах. Оставайтесь на связи. Комплексный исходник можно будет скачать в последнем посте.
getPR на платформе x64 работает? я ту же функцию использовал, но на сервере x64 глючила - пришлось подпорки делать для этой архитектуры.
как вариант, можно вызывать через exec перловый скрип (use WWW::Google::PageRank) - вызов в 2 строки, считает быстро и надежно
Вообще работает и без проблем. Но тут трудно что-то сказать утвердительно.
Нужно попробовать. Спасибо
Проверяю 10 сайтов в цыкле, нужен PR для дальнейшего анализа. Что вы можете посоветовать. Доходит до $pos = strpos($data, "Rank_"); и ничего не находит.
Алгоритм поменялся. Погуглить на эту тему
Гуглил и нашел еще 3 нерабочих алгоритма ). Жаль нет API как в случаи с поиском.
Отправить комментарий