A raiz de la instalación de un plugin de Wordpress que daba fallos, me puse a buscar una forma para consultar el PageRank de Google desde un script en PHP.
Como todos sabemos, Google dispone de una API gracias la cuál nos conectamos y solicitamos el PageRank, pero podemos emular la llamada de la Barra de Google vía PHP y lanzar la petición, para recoger un XML con información varia, entre ella, el preciado PageRank.
Estuve buscando varias alternativas por la blogosfera, y aunque hay varios, no todos acabaron funcionando. A continuación presento y explico el único que me funcionó. Siento no mencionar el autor... no me guardé la referencia.
Actualizado: He colgado el código fuente de la función para evitar más confusiones provocadas por el visualizador de código. Ver el final del artículo.
El proceso se basa en emular la petición que realiza la Barra de Google. Para tal efecto son necesarias otras funciones que realizan el trabajo sucio de preparar ciertos datos para la petición. Estas funciones son las siguientes:
PHP:
-
function zeroFill($a, $b)
-
{
-
-
if ($z & $a)
-
{
-
$a = ($a>>1);
-
$a &= (~$z);
-
$a |= 0x40000000;
-
$a = ($a>>($b-1));
-
}
-
else
-
{
-
$a = ($a>>$b);
-
}
-
return $a;
-
}
-
-
function toInt32(& $x){
-
-
$y = (int)$x;
-
if($y==-$z&&$x<-$z){
-
$y = (int)((-1)*$x);
-
$y = (-1)*$y;
-
}
-
$x = $y;
-
}
-
-
function mix($a,$b,$c) {
-
$a -= $b; $a -= $c; toInt32($a); $a = (int)($a ^ (zeroFill($c,13)));
-
$b -= $c; $b -= $a; toInt32($b); $b = (int)($b ^ ($a<<8));
-
$c -= $a; $c -= $b; toInt32($c); $c = (int)($c ^ (zeroFill($b,13)));
-
$a -= $b; $a -= $c; toInt32($a); $a = (int)($a ^ (zeroFill($c,12)));
-
$b -= $c; $b -= $a; toInt32($b); $b = (int)($b ^ ($a<<16));
-
$c -= $a; $c -= $b; toInt32($c); $c = (int)($c ^ (zeroFill($b,5)));
-
$a -= $b; $a -= $c; toInt32($a); $a = (int)($a ^ (zeroFill($c,3)));
-
$b -= $c; $b -= $a; toInt32($b); $b = (int)($b ^ ($a<<10));
-
$c -= $a; $c -= $b; toInt32($c); $c = (int)($c ^ (zeroFill($b,15)));
-
-
}
-
-
function GoogleCH($url, $length=null, $init=GOOGLE_MAGIC) {
-
-
-
}
-
$a = $b = 0x9E3779B9;
-
$c = $init;
-
$k = 0;
-
$len = $length;
-
while($len>= 12) {
-
$a += ($url[$k+0] +($url[$k+1]<<8) +($url[$k+2]<<16) +($url[$k+3]<<24));
-
$b += ($url[$k+4] +($url[$k+5]<<8) +($url[$k+6]<<16) +($url[$k+7]<<24));
-
$c += ($url[$k+8] +($url[$k+9]<<8) +($url[$k+10]<<16)+($url[$k+11]<<24));
-
$mix = mix($a,$b,$c);
-
$a = $mix[0]; $b = $mix[1]; $c = $mix[2];
-
$k += 12;
-
$len -= 12;
-
}
-
-
$c += $length;
-
switch($len) /* all the case statements fall through */
-
{
-
case 11: $c+=($url[$k+10]<<24);
-
case 10: $c+=($url[$k+9]<<16);
-
case 9 : $c+=($url[$k+8]<<8);
-
/* the first byte of c is reserved for the length */
-
case 8 : $b+=($url[$k+7]<<24);
-
case 7 : $b+=($url[$k+6]<<16);
-
case 6 : $b+=($url[$k+5]<<8);
-
case 5 : $b+=($url[$k+4]);
-
case 4 : $a+=($url[$k+3]<<24);
-
case 3 : $a+=($url[$k+2]<<16);
-
case 2 : $a+=($url[$k+1]<<8);
-
case 1 : $a+=($url[$k+0]);
-
/* case 0: nothing left to add */
-
}
-
$mix = mix($a,$b,$c);
-
/*-------------------------------------------- report the result */
-
return $mix[2];
-
}
-
-
//converts a string into an array of integers containing the numeric value of the char
-
function strord($string) {
-
for($i=0;$i)
-
{
-
$result[$i] =
ord($string{$i});
-
}
-
return $result;
-
}
-
-
// converts an array of 32 bit integers into an array with 8 bit values. Equivalent to (BYTE *)arr32
-
-
function c32to8bit($arr32) {
-
for($i=0;$i)
-
{
-
for ($bitOrder=$i*4;$bitOrder<=$i*4+3;$bitOrder++) {
-
$arr8[$bitOrder]=$arr32[$i]&255;
-
$arr32[$i]=zeroFill($arr32[$i], 8);
-
}
-
}
-
return $arr8;
-
}
Si nos fijamos en las funciones veremos que casi todas son de conversiones de datos, mover bits de un sitio a otro, con el fin de obtener el checksum (GoogleCH), que viene a ser la forma que tiene Google de verificar la procedencia de una petición.
Si miramos mas atentamente la función de checksum, veremos que agrega un parámetro por defecto llamado init, con el valor GOOGLE_MAGIC. Esto es una constante que actúa como llave y que se debe definir en el inicio del script de la siguiente forma:
PHP:
-
define('GOOGLE_MAGIC', 0xE6359A60
);
Llegados a este punto, sólo nos queda montar la petición propiamente. En la función recogeremos el valor del PageRank y lo devolveremos. La función es la siguiente:
PHP:
-
function get_page_rank($url){
-
-
$reqgr = "info:".$url;
-
-
$gch = "6".GoogleCH(strord($reqgr));
-
$fsock =
fsockopen('toolbarqueries.google.com',
80,
$errno,
$errstr);
-
if ( !$fsock ){
-
echo 'Can not connect to server';
-
return -1;
-
}
-
$base_get = "/search?client=navclient-auto&ch=".$gch."&ie=UTF-8&oe=UTF-8&features=Rank:FVN&q=".$reqgre;
-
fputs($fsock,
"GET $base_get HTTP/1.1\r\n");
-
fputs($fsock,
"HOST: toolbarqueries.google.com\r\n");
-
fputs($fsock,
"User-Agent: Mozilla/4.0 (compatible; GoogleToolbar 2.0.114-big; Windows XP 5.1)\r\n");
-
fputs($fsock,
"Connection: close\r\n\r\n");
-
-
$res['content'] .=
fread($fsock,
1024);
-
}
-
-
if(preg_match('/Rank_.*?:.*?:(\d+)/i',
$res['content'],
$m)){
-
return $m[1];
-
}else{
-
return -1;
-
}
-
}
Como vemos, primero se prepara el parámetro a enviar (la URL), generamos el checksum según dicho parámetro, abrimos un socket y le enviamos la petición emulando que somos un navegador. Luego leemos la respuesta del mismo socket y cerramos la conexión al terminar.
Acto seguido parseamos la respuesta con una expresión regular que buscará el valor numérico del PageRank y lo devolverá (si no lo encuentra, devuelve -1). Y ya está.
Entonces, en el cuerpo del script PHP llamaremos a esta última función para obtener el PageRank:
PHP:
-
$pagerank = get_page_rank($url);
donde $url es la típica variable string con la dirección de la que queremos obtener el PageRank. No olvidar que debemos introducir http:// en la URL y que dará resultados distintos para URLs con o sin el www (http://www.syntaxerror.es es diferente a http://syntaxerror.es)
Nota: Debido a ciertos problemas con el visualizador de código, cuelgo a continuación un script php con el conjunto de funciones aquí explicadas para que no se genere más confusión. Podeis descargarlo desde aquí: PageRank.phps. Le cambiais la extensión a .php y llamais a la función get_page_rank() pasándole una URL.
Saludos!
Tag:
Escribe un Comentario