PHP: Script para consultar el PageRank
24 de Julio de 2007 en Programación, PHP
Lecturas: 5,235

PageRankA 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:
  1. function zeroFill($a, $b)
  2. {
  3. $z = hexdec(80000000);
  4. if ($z & $a)
  5. {
  6. $a = ($a>>1);
  7. $a &= (~$z);
  8. $a |= 0x40000000;
  9. $a = ($a>>($b-1));
  10. }
  11. else
  12. {
  13. $a = ($a>>$b);
  14. }
  15. return $a;
  16. }
  17.  
  18. function toInt32(& $x){
  19. $z = hexdec(80000000);
  20. $y = (int)$x;
  21. if($y==-$z&&$x<-$z){
  22. $y = (int)((-1)*$x);
  23. $y = (-1)*$y;
  24. }
  25. $x = $y;
  26. }
  27.  
  28. function mix($a,$b,$c) {
  29. $a -= $b; $a -= $c; toInt32($a); $a = (int)($a ^ (zeroFill($c,13)));
  30. $b -= $c; $b -= $a; toInt32($b); $b = (int)($b ^ ($a<<8));
  31. $c -= $a; $c -= $b; toInt32($c); $c = (int)($c ^ (zeroFill($b,13)));
  32. $a -= $b; $a -= $c; toInt32($a); $a = (int)($a ^ (zeroFill($c,12)));
  33. $b -= $c; $b -= $a; toInt32($b); $b = (int)($b ^ ($a<<16));
  34. $c -= $a; $c -= $b; toInt32($c); $c = (int)($c ^ (zeroFill($b,5)));
  35. $a -= $b; $a -= $c; toInt32($a); $a = (int)($a ^ (zeroFill($c,3)));
  36. $b -= $c; $b -= $a; toInt32($b); $b = (int)($b ^ ($a<<10));
  37. $c -= $a; $c -= $b; toInt32($c); $c = (int)($c ^ (zeroFill($b,15)));
  38. return array($a,$b,$c);
  39. }
  40.  
  41. function GoogleCH($url, $length=null, $init=GOOGLE_MAGIC) {
  42. if(is_null($length)) {
  43. $length = sizeof($url);
  44. }
  45. $a = $b = 0x9E3779B9;
  46. $c = $init;
  47. $k = 0;
  48. $len = $length;
  49. while($len>= 12) {
  50. $a += ($url[$k+0] +($url[$k+1]<<8) +($url[$k+2]<<16) +($url[$k+3]<<24));
  51. $b += ($url[$k+4] +($url[$k+5]<<8) +($url[$k+6]<<16) +($url[$k+7]<<24));
  52. $c += ($url[$k+8] +($url[$k+9]<<8) +($url[$k+10]<<16)+($url[$k+11]<<24));
  53. $mix = mix($a,$b,$c);
  54. $a = $mix[0]; $b = $mix[1]; $c = $mix[2];
  55. $k += 12;
  56. $len -= 12;
  57. }
  58.  
  59. $c += $length;
  60. switch($len)              /* all the case statements fall through */
  61. {
  62. case 11: $c+=($url[$k+10]<<24);
  63. case 10: $c+=($url[$k+9]<<16);
  64. case 9 : $c+=($url[$k+8]<<8);
  65. /* the first byte of c is reserved for the length */
  66. case 8 : $b+=($url[$k+7]<<24);
  67. case 7 : $b+=($url[$k+6]<<16);
  68. case 6 : $b+=($url[$k+5]<<8);
  69. case 5 : $b+=($url[$k+4]);
  70. case 4 : $a+=($url[$k+3]<<24);
  71. case 3 : $a+=($url[$k+2]<<16);
  72. case 2 : $a+=($url[$k+1]<<8);
  73. case 1 : $a+=($url[$k+0]);
  74. /* case 0: nothing left to add */
  75. }
  76. $mix = mix($a,$b,$c);
  77. /*-------------------------------------------- report the result */
  78. return $mix[2];
  79. }
  80.  
  81. //converts a string into an array of integers containing the numeric value of the char
  82. function strord($string) {
  83. for($i=0;$i)
  84. {
  85. $result[$i] = ord($string{$i});
  86. }
  87. return $result;
  88. }
  89.  
  90. // converts an array of 32 bit integers into an array with 8 bit values. Equivalent to (BYTE *)arr32
  91.  
  92. function c32to8bit($arr32) {
  93. for($i=0;$i)
  94. {
  95. for ($bitOrder=$i*4;$bitOrder<=$i*4+3;$bitOrder++) {
  96. $arr8[$bitOrder]=$arr32[$i]&255;
  97. $arr32[$i]=zeroFill($arr32[$i], 8);
  98. }
  99. }
  100. return $arr8;
  101. }

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:
  1. 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:
  1. function get_page_rank($url){
  2. $url = preg_replace('/\?.*$/','?',$url);
  3. $reqgr = "info:".$url;
  4. $reqgre = "info:".urlencode($url);
  5. $gch = "6".GoogleCH(strord($reqgr));
  6. $fsock = fsockopen('toolbarqueries.google.com', 80, $errno, $errstr);
  7. if ( !$fsock ){
  8. echo 'Can not connect to server';
  9. return -1;
  10. }
  11. $base_get = "/search?client=navclient-auto&ch=".$gch."&ie=UTF-8&oe=UTF-8&features=Rank:FVN&q=".$reqgre;
  12. fputs($fsock, "GET $base_get HTTP/1.1\r\n");
  13. fputs($fsock, "HOST: toolbarqueries.google.com\r\n");
  14. fputs($fsock, "User-Agent: Mozilla/4.0 (compatible; GoogleToolbar 2.0.114-big; Windows XP 5.1)\r\n");
  15. fputs($fsock, "Connection: close\r\n\r\n");
  16. while(!feof($fsock)){
  17. $res['content'] .= fread($fsock, 1024);
  18. }
  19. fclose($fsock);
  20. if(preg_match('/Rank_.*?:.*?:(\d+)/i', $res['content'], $m)){
  21. return $m[1];
  22. }else{
  23. return -1;
  24. }
  25. }

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:
  1. $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:
 Enviar a Fresqui

Leer los Comentarios

[ # 3073 ] Comment desde Italico [26 de Julio de 2007, 01:52]

Hola!
Es increhible de complicado ese código :)

Disculpame, pero te molesto porque estoy empezando un DIRECTORIO WEB como Blog Catalog y otros… y me gustaria que listaras en él ;)

Como te imaginarás es complicado al principio…asi que estoy buscando apoyo en la red.

Si pudieras poner el boton… [esta en www.betadir.com] me harias un GRAN favor :)

Enviame un correo a italoarg76@gmail.com si te sumas a mi listado asi… te agrego en el ;)

Salu2 y excelente blog.

[ # 3080 ] Comment desde Xavi [26 de Julio de 2007, 07:17]

Si, almenos las funciones de apoyo son ya de nivel experto ;)

Sobre tu directorio, te respondo por correo ;)

[ # 4119 ] Comment desde hispah [25 de Agosto de 2007, 02:24]

No puedes hacer el ejemplo para descargar?

saludos,

[ # 4120 ] Comment desde Xavi [25 de Agosto de 2007, 02:36]

A ver, sólo tienes que meter todo el código que hay aquí en un archivo PHP (no olvides sus tags) y llamarlo con la última instrucción del artículo. No es para nada difícil…

[ # 4456 ] Comment desde gmb [31 de Agosto de 2007, 02:05]

Teneis otro ejemplo que funciona en www.ejecutar.es

[ # 4457 ] Comment desde Xavi [31 de Agosto de 2007, 02:16]

Gracias. Este no lo habia probado.

[ # 4823 ] Comment desde Luis Dillon [07 de Septiembre de 2007, 03:16]

Veo dos líneas con el siguiente código incompleto

“for($i=0;$i”

en funciones c32to8bit y strord. Soy yo o es mi navegador?

Navegador: Firefox 2.0, Plataforma: Suse 10.2/Linux

[ # 4837 ] Comment desde Xavi [07 de Septiembre de 2007, 10:08]

Efectivamente, faltava un paréntesis y una llave de apertura en los dos for’s…

Gracias por el aviso, Luis! :)

[ # 6698 ] Comment desde Artefio [09 de Octubre de 2007, 01:46]

Pues no te parece que si el codigo esta erroneo, seria buena idea que lo corigieras y repostearas? yo tambien me encontre con el mismo error.

Saludos…

[ # 6699 ] Comment desde Artefio [09 de Octubre de 2007, 01:50]

To lo edite asi pero el codigo no funciona

function strord($string) {
for($i=0;$i;){
$result[$i] = ord($string{$i});
}
return $result;
}

o sea mi sitio tiene un pr de 2, pero el script me arroja un -1
de todas formas no digo que funcione mal por esto sino porque yahoo tiene un pr de 10 y tambien me da -1 ;)

Seria bueno ver donde esta el error, si es que el script realmente funciona.

Saludos…

[ # 6702 ] Comment desde Xavi [09 de Octubre de 2007, 02:24]

Pues con todos los respetos, el código funciona. Lo puedes ver funcionando arriba a la derecha, en el apartado de Estadísticas (se despliega). A mi me da el PageRank correcto.
Saludos.

[ # 6864 ] Comment desde oskar [12 de Octubre de 2007, 04:37]

mandarme ejemplos de html y php

[ # 6911 ] Comment desde Xavi [12 de Octubre de 2007, 10:27]

Cógelo todo y mételo en un archivo PHP entre sus tags, y al final pones

print get_page_rank($url);

Ala.

[ # 11312 ] Comment desde ASLAN [10 de Diciembre de 2007, 02:36]

Da error en la esta parte

for($i=0;$i)
{

[ # 11329 ] Comment desde Xavi [10 de Diciembre de 2007, 09:07]

Vale, he acabado harto de los fallos que me da el visualizador de código. He puesto el código completo en un archivo descargable. Ver el final del artículo.

[ # 30221 ] Comment desde Jair Sarmiento [28 de Julio de 2008, 04:26]

Hola…. wuaau es super complicado ese codigo eres un duro vacano lo probe y funciona al pelo .

Excelente

Escribe un Comentario





Estadísticas