Программное обеспечение, Личные разработки, Проекты, Портфолио, Хитрости, Заметки, Статьи...

Google PageRank API. Определяем PR страницы своими силами.

Google PageRankПрактически каждый знает что такое Google PageRank, а кто не знает - смело идем на википедю (ru.wikipedia.org/wiki/PageRank) и читаем. Но не каждый знает как его получить своими силами. Большинству пользователей интернет это конечно и не нужно знать, но большому количеству держателей сайтов этот прием несомненно пригодится. Можно конечно залезть в Google Webmaster Tools и посмотреть его для своих сайтов, можно установить Google Toolbar, можно воспользоваться одним из многочисленных бесплатных (платных) сервисов по определению PR, можно поставить счетчик PR на свою страницу, можно даже купить готовый скрипт определения PR... Но также можно написать скрипт самому =) Собственно об этом я и расскажу.
Переходим сразу к делу, тобишь к программе, а точнее к ее исходному коду. Назовем эту разработку Google PageRank API, раз уж гугл такой API не предоставляет, то предоставлю я =).

Предлагаю вашему вниманию код определения Google PR на языке python. Код нашел в сети с ошибкой. Также нашел исправления алгоритма. Выкладываю полностью работоспособный код.
#!/usr/local/bin/env python
# -*- coding: utf-8 -*-
# (C) 2008 Fred Cirera
# ported in Python from the Ruby code by Vsevolod S. Balashov
# fixed error with algorythm by Konstantin S. Dyakoff
# http://madjack.ru/developer/2009/10/google-pagerank-api.html
# http://snippets.dzone.com/posts/show/3284

import urllib2
import re
import time
import sys

from urllib import urlencode
from pprint import pprint

HOST = "toolbarqueries.google.com"

def mix(a, b, c): 
    M = lambda v: v % 0x100000000 # int32 modulo 
    a, b, c = (M(a), M(b), M(c))
    
    a = M((a-b-c) ^ (c >> 13))
    b = M((b-c-a) ^ (a <<  8))
    c = M((c-a-b) ^ (b >> 13))

    a = M((a-b-c) ^ (c >> 12))
    b = M((b-c-a) ^ (a << 16))
    c = M((c-a-b) ^ (b >> 5))

    a = M((a-b-c) ^ (c >>  3))
    b = M((b-c-a) ^ (a << 10))
    c = M((c-a-b) ^ (b >> 15))

    return a, b, c

def checksum(iurl):
    C2I = lambda s: sum(c << 8*i for i, c in enumerate(s[:4]))
    
    a, b, c = 0x9e3779b9, 0x9e3779b9, 0xe6359a60
    lg  = len(iurl)
    k = 0
    
    while k <= lg-12:
        a = a + C2I(iurl[k:k+4])
        b = b + C2I(iurl[k+4:k+8])
        c = c + C2I(iurl[k+8:k+12])
        a, b, c = mix(a, b, c)
        k += 12

    a = a + C2I(iurl[k:k+4])
    b = b + C2I(iurl[k+4:k+8])
    c = c + (C2I(iurl[k+8:])<<8) + lg
    a, b, c = mix(a, b, c)
    return c

def GoogleHash(value):
    I2C = lambda i: [i & 0xff, i >> 8 & 0xff,  i >> 16 & 0xff, i >> 24 & 0xff]
    ch = checksum([ord(c) for c in value])
    ch = ((ch % 0x0d) & 7) | ((ch/7) << 2)
    
    return "6%s" % checksum(sum((I2C(ch-9*i) for i in range(20)), []))


def make_url(host, site_url):
    url = "info:" + site_url
    ghash = GoogleHash(url)
    params = dict(client="navclient-auto", ch="%s" % ghash,
                  ie="UTF-8", oe="UTF-8", features="Rank", q=url)
    return "http://%s/search?%s" % (host, urlencode(params))


# Where the fun begins

if __name__ == "__main__":
    if len(sys.argv) != 2:
        url = 'http://www.google.com/'
    else:
        url = sys.argv[1]

    if not url.startswith('http://'):
        url = 'http://%s' % url

    print make_url(HOST, url)
    req = urllib2.Request(make_url(HOST, url))
    try:
        f = urllib2.urlopen(req)
        response = f.readline()
    except Exception, err:
        print err
        # print err.read()
        sys.exit(1)
        
    try:
        rank = re.match(r'^Rank_\d+:\d+:(\d+)', response.strip()).group(1)
    except AttributeError:
        print "This page is not ranked"
        rank = -1

    print "PagerRank: %d\tURL: %s" % (int(rank), url)
Я уже предвкушаю Ваш вопрос "А где ж код на PHP или на худой конец на PERL?!". Несложными манипуляциями код написал собственными руками основываясь на вышеприведенном исходнике и охотно им делюсь:
#!/usr/local/bin/perl
# (C) 2008 Fred Cirera
# ported in Perl from the Python code by Konstantin S. Dyakoff
# http://madjack.ru/developer/2009/10/google-pagerank-api.html

package PR;

use Acme::Lambda;
use URI::Escape;
use LWP::UserAgent;

sub mix{
    my $a = shift;
    my $b = shift;
    my $c = shift;
    my $M = lambda {$_ % 0x100000000};

    $a = $M->($a);
    $b = $M->($b);
    $c = $M->($c);
    
    $a = $M->(($a-$b-$c) ^ ($c >> 13));
    $b = $M->(($b-$c-$a) ^ ($a <<  8));
    $c = $M->(($c-$a-$b) ^ ($b >> 13));
    
    $a = $M->(($a-$b-$c) ^ ($c >> 12));
    $b = $M->(($b-$c-$a) ^ ($a << 16));
    $c = $M->(($c-$a-$b) ^ ($b >> 5));
    
    $a = $M->(($a-$b-$c) ^ ($c >>  3));
    $b = $M->(($b-$c-$a) ^ ($a << 10));
    $c = $M->(($c-$a-$b) ^ ($b >> 15));

    return ($a, $b, $c);
}

sub C2I{
    my $len = pop;
    my $from = pop;
    my @arr = @_;
    my $sum = 0;
    
    my $j = 0;
    for my $i ($from..$len){
	$sum += $arr[$i] << (8 * $j++);
    }
    return $sum;
}

sub checksum{
    my @iurl = @_;    
    my ($a, $b, $c) = (0x9e3779b9, 0x9e3779b9, 0xe6359a60);
    
    my $lg  = scalar(@iurl);
    my $k = 0;
    while($k <= $lg-12){
        $a = $a + C2I(@iurl, $k, $k+3);
        $b = $b + C2I(@iurl, $k+4, $k+7);
        $c = $c + C2I(@iurl, $k+8, $k+11);
        ($a, $b, $c) = mix($a, $b, $c);
        $k += 12;
    }
    
    $a = $a + C2I(@iurl, $k, $k+4);
    $b = $b + C2I(@iurl, $k+4, $k+8);
    $c = $c + (C2I(@iurl, $k+8, $k+scalar(@iurl))<<8) + $lg;
    ($a, $b, $c) = mix($a, $b, $c);
    return $c;
}

sub I2C{
    my $i = shift;
    return ($i & 0xff, $i >> 8 & 0xff, $i >> 16 & 0xff, $i >> 24 & 0xff);
}

sub GoogleHash{
    my $value = shift;
    @va = split '', $value;
    for $i (0..scalar(@va)-1){
	$va[$i] = ord($va[$i]);
    }
    $ch = checksum(@va);
    $ch = (($ch % 0x0d) & 7) | (($ch/7) << 2);
    
    my $sum;
    my $j = 0;
    for $i (0..19){
	($sum[$j++], $sum[$j++], $sum[$j++], $sum[$j++]) = I2C($ch-9*$i);
    }
    
    return sprintf("6%s", checksum(@sum));
}

sub MakePRQuery{
    my $url = shift;
    $url = "info:$url";
    return sprintf("http://toolbarqueries.google.com/search?q=%s&ch=%d&features=%s&oe=%s&ie=%s&client=%s", 
	uri_escape($url), GoogleHash($url), "Rank", "UTF-8", "UTF-8", "navclient-auto");
}

sub QueryPR{
    my $url = shift;
    $url = MakePRQuery($url);
    
    my $a = LWP::UserAgent->new(
	agent => "Mozilla/4.0 (compatible; GoogleToolbar 2.0.108-big; Windows XP 5.1)",
    );
    $a->timeout(30);
    $a->env_proxy;
    my $r = $a->get($url);

    if($r->is_success){
	my @data = split ":", $r->content;
	if(scalar(@data) eq 3){
	    return $data[2];
	}
    }
    return -1;
}

1;
Как видно это модуль PR.pm. Его можно кинуть в папку с любым другим приложением, которое будет его пользовать и просто подключить. Ниже прилагаю пример:
#!/usr/local/bin/perl

use PR;

print "PR: " . PR::QueryPR("http://www.madjack.ru") . "\n";
Пользуйтесь на здоровье. Если нашли ошибку в коде или у вас есть пожелания или просто отзывы - пишите в комментариях или мне на почту: me (at) madjack (dot) ru

Комментариев: 11

Спасибо за код на питоне ;)
Щас попробую это дело обернуть в класс.
И сделать масс-чекер с задержками.
Кстати, а у гугл-тулбара есть лимит запросов в сутки или типа того?

Пока замечено небыло, но все возможно. Если теоретически предположить что рядовой юзер в сутки посещает несколько тысяч страниц, и для каждой тулбар определяет ПР, то врятли есть какие-то ограничения. Главное не спалиться, что это не тулбар=) И еще. Не слать с 1 айпи адреса запросы слишком часто. Это мое мнение. Классиком поделишься потом? Мы его сюда как продолжение определим=)

А на пхп , пожалуйста )

Ну с перла на ПХП переписать вообще никакого труда. Наверное и сам сможешь=)

Блин...динозавры ещё живы....я думал уже все умерли.......только они выкладывают код на perl и говорят, что можете переписать на php.......

И ниче не динозавры. А просто опытные люди которым лень переводить перл на пхп.

Почему скрипт не работает на моём сайте?

Действительно, Сереня, почему?

Джек, php код в студию!

А самому слабо перевести PERL в PHP?=)

Собственно уже перевели код на PHP здесь http://info.sectorit.net/index.php/development/php/92--pagerank-

Комментировать

OpenID принимается здесь Узнать больше об OpenID
  • Rambler's Top100

Об этой записи

Сообщение опубликовано 25.10.2009 18:15. Автор — Безумный Джек.

Предыдущая запись — Как с проверить валидность EMail адреса?

Следующая запись — Как обновить систему при помощи csup?

Смотрите новые записи на главной странице или загляните в архив, где есть ссылки на все сообщения.