#!/usr/bin/perl
#===============================================================================
#         FILE:  yaextlink.pl
#        USAGE:  perl ./yaextlink.pl
#                или добавить в cron для запуска по расписанию.
#
#  DESCRIPTION:  Скрипт для получения количества ссылающихся сайтов и количества
#                внешних ссылок на целевой сайт, определенных сервисом
#                Яндекс.Вебмастер.
#
#      OPTIONS:  Все настройки указываются в теле скрипта
# REQUIREMENTS:  perl v. 5.8.8 или выше
#       AUTHOR:  Dimio (dimio.org), dimio@dimio.org
#      VERSION:  0.1
#===============================================================================
require 5.008_008;
use warnings;
use strict;
use utf8;
use LWP::UserAgent;
use HTTP::Cookies;
local $| = 1;

# список сайтов из Яндекс.Вебмастер, который нужно обработать
# (название произвольное, цифры - id сайта (скопир. из я.вебмастер))
my $hosts = {
    'dimio.org'     => '0000001',
    'dimio-blog.lj' => '0000002',
};

# настройки скрипта - логин и пароль от яндекса,
# путь к директории, в которой будут храниться файлы с кол-вом ссылок
my $options = {
    ya_login        => 'my_login',
    ya_pass         => 'my_password',
    savedir         => '/path/to/save/',

    ya_count_url    => 'http://webmaster.yandex.ru/site/indexed/links.xml?path=*&host=',
    ya_login_url    => 'https://passport.yandex.ru/passport?mode=auth',
    ya_logout_url   => 'https://passport.yandex.ru/passport?mode=logout',
};


# конструктор "браузера" через libwww
my $ua = ua_init();

# логинимся на сервисы яндекса, при невозможности будет выход
ya_login($ua, $options);

# формируется строка с текущей датой
# (будет напечатана в файлах перед кол-вом вход. ссылок)
my $localdate = get_localdate();

foreach my $host (keys %$hosts) {
    # получить кол-во ссылающихся сайтов и кол-во внешних ссылок
    # для каждого сайта из списка hosts
    my ($sites, $links) = ya_get_links_cnt( $hosts->{$host}, $ua, $options );
    #print "$host \t $sites $links \n";

    # сохранить в файле кол-во ссыл-ся сайтов и кол-во внешних ссылок
    print_to_file( $host, $options, $localdate, $sites, $links );
}

ya_logout($ua, $options);
exit;
# конец работы


# сохранение результатов работы скрипта в файл .csv в директории savedir,
# имя файла = названию текущего сайта
sub print_to_file {
    my $host = shift;
    my $opt = shift;
    my ($localdate, $sites, $links) = @_;

    my $output_file = $opt->{savedir} . $host . '.csv';

    open( my $output_file_fh, '>>:encoding(UTF-8)', $output_file )
        or die "Can't open output file $output_file : $!\n";

    print {$output_file_fh}
        join( q{;}, $localdate, $sites, $links ), "\n";

    close($output_file_fh) or warn "Unable to close $output_file : $!\n";
}

# создание текущей даты в виде ГГГГ-ММ-ДД
# (libreoffice-calc понимает такой формат "на лету")
sub get_localdate {
    my ($DAY, $MONTH, $YEAR) = (localtime)[3..5];

    # привести дату к обычному формату
    $MONTH += 1;
    $YEAR += 1900;

    return join('-', $YEAR, $MONTH, $DAY);
}

# получение кол-ва ссылающихся сайтов и кол-ва внешних ссылок
# на текщий целевой сайт со страницы Яндекс.Вебмастер
sub ya_get_links_cnt {
    my $host_id = shift;
    my ($ua, $opt) = @_;

    my $response = $ua->get( $opt->{ya_count_url} . $host_id );
        #warn "$response->status_line\n" unless $response->is_success;
    my @links_cnt = $response->decoded_content =~
        m{ 
Ссылающихся \s сайтов: \s+ (\d+), \s+ внешних \s ссылок \s \(приблизительно\): \s+ (\d+) \s
}msx; return ($links_cnt[0], $links_cnt[1]); } # вход в сервисы Яндекса для работы с я.вебмастер. # idkey получается со страницы логина, # timestamp - "время с начала эпохи" в мс (ф-я java getTime) # from - от какого сервиса перешли на страницу логина sub ya_login { my ($ua, $opt) = @_; my $response = $ua->post( $opt->{ya_login_url}, [ 'from' => 'passport', 'idkey' => ya_get_idkey($ua, $options), 'display' => 'page', 'login' => $opt->{ya_login}, 'passwd' => $opt->{ya_pass}, 'timestamp' => time * 1000, ]); die "$response->status_line\n" unless $response->is_success; } # получение значения idkey (скрытое поле формы для входа в Яндекс), # берется из кода страницы логина sub ya_get_idkey { my ($ua, $opt) = @_; my $response = $ua->get( $opt->{ya_login_url} ); die "$response->status_line\n" unless $response->is_success; #my $idkey = $1 if my @idkey = $response->decoded_content =~ m{ name="idkey" \s value="([\d\w]{22})" \s /> }msx; return $idkey[0]; #return $idkey; } # отлогиниваемся от яндекса sub ya_logout { my ($ua, $opt) = @_; my $response = $ua->get( $opt->{ya_logout_url} ); warn "$response->status_line\n" unless $response->is_success; } # создает "браузер" с указанными настройками (принимать куки, # следовать по автопереходам страниц, имитировать firefox) sub ua_init { my $cookies = HTTP::Cookies->new('file'=>'./cookies.lwp','autosave'=>0); my $browser = LWP::UserAgent->new('agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11)', 'cookie_jar' => $cookies, 'requests_redirectable' => ['GET', 'POST']); $browser->default_header('Accept' => 'text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1', 'Accept-Charset' => 'utf-8; *;q=0.1', 'Accept-Language' => 'ru,en-us;q=0.7,en;q=0.3', 'Accept-Encoding' => 'deflate, gzip, x-gzip, identity, *;q=0', ); $browser->timeout(120); # при таймауте свыше 2 минут - закрывать соединение return $browser; }