Компонент вычисления 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>Анализ сайта &#8594;<span style=float:right><img src=http://favicon.yandex.net/favicon/".$url." /><a href=http://".$url." target=_blank rel=nofollow>".$url."&#8658;</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>Анализ сайта &#8594;<span style=float:right><img src=http://favicon.yandex.net/favicon/".$url." /><a href=http://".$url." target=_blank rel=nofollow>".$url."&#8658;</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);
	}
}

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

E-Will

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

как вариант, можно вызывать через exec перловый скрип (use WWW::Google::PageRank) - вызов в 2 строки, считает быстро и надежно

shift-web

Вообще работает и без проблем. Но тут трудно что-то сказать утвердительно.

как вариант, можно вызывать через exec перловый скрип (use WWW::Google::PageRank)

Нужно попробовать. Спасибо

Дизайн студия ProGrafika

Проверяю 10 сайтов в цыкле, нужен PR для дальнейшего анализа. Что вы можете посоветовать. Доходит до $pos = strpos($data, "Rank_"); и ничего не находит.

shift-web

Алгоритм поменялся. Погуглить на эту тему

Дизайн студия ProGrafika

Гуглил и нашел еще 3 нерабочих алгоритма ). Жаль нет API как в случаи с поиском.

Отправить комментарий