#!/usr/bin/perl
#===============================================================================
#  DESCRIPTION:  Anonymizer checker - скрипт для проверки списка анонимайзеров
#                на работоспособность. Имеется возможность создания списка
#                путём парсинга поисковой выдачи Google.
#
#        USAGE:  anocheck.pl -i [input_method] -g [good_proxy_file]
#                -b [bad_proxy_file]
#
#      OPTIONS:  -i [input_method]: google, ajax or .txt file
#                -g [good_proxy]: filename for save work proxy
#                -b [bad_proxy]: filename for save not work proxy
#
#       AUTHOR:  dimio
#          URL:  http://www.dimio.org
#      VERSION:  0.6
#      CREATED:  2010-08-25
#===============================================================================
require 5.8.8;
use warnings;
use strict;
use LWP::UserAgent;
use HTTP::Cookies;
use MIME::Base64;
use Getopt::Std;
use utf8;
#===============================================================================
$| = 1;
our $VERSION = 0.6;

my %options = (                     # Настройки по умолчанию:
    'i'     => 'good.txt',          # файл со списком анонимайзеров
    'g'     => 'good.txt',          # имя файла для вывода рабочих анонимайзеров
    'b'     => 'bad.txt',           # то же для нерабочих
);
getopts('i:g:b:rh', \%options);

# Вывод справки и завершение работы программы
if ($options{h}) {
    usage($VERSION);
    exit;
}

# Формат запроса для поиска определённых типов анонимайзеров
# 1 - на движке PHPProxy
my $phproxy_sreq = '"Rotate13" "Base64" "Strip" inurl:index.php?q=';
# 2 - на движке Glype
my $glype_sreq = '"Encode URL" "Allow Cookies" "Remove Scripts" inurl:browse.php?u=';

#===============================================================================
my %proxy_list;
my $ua = UAInit();

# Проверка на работоспособность анонимайзеров, перечисленных в указанном файле
if ( $options{i} ne 'google' && -s $options{i} ) {
    print 'Read proxy from '.$options{i},"...\n";
    ReadProxyFile(\%options, \%proxy_list);
    print "Done\n";
}
# Составление списка анонимайзеров при помощи веб-поиска Google
elsif ($options{i} eq 'google'){
    GetProxyList_Web($ua,\%proxy_list,$phproxy_sreq,$glype_sreq);
}
# Составление списка анонимайзеров через API Google
# (выдача очень маленькая по сравнению с веб-поиском)
elsif ($options{i} eq 'ajax') {
    GetProxyList_Ajax($ua,\%proxy_list,$phproxy_sreq);
}

# Проверка списка анонимайзеров на валидность, разделение рабочих и нерабочих
my $bad_proxy_list = CheckProxy($ua,\%proxy_list);

# Сохранение результатов проверки в файлах
SaveResult(\%options,\%proxy_list,$bad_proxy_list);


exit 0;
#===============================================================================

sub GetProxyList_Web {
    # Получение списка анонимайзеров через веб-поиск Google
    my ($ua,$proxy_list,$phproxy_sreq,$glype_sreq) = @_;

    # Поиск анонимайзеров. Разбит на 2 цикла для удобства возможного разнесения
    # результатов поиска в будущем.
    # 1 - искать основанные на движке PHProxy
    print "\nGetting PHProxy from Google search\n";
    for (my $page= 0; $page<= 400; $page+= 100){ # парсинг первых 5 страниц найденного
        print '.';

        my $google_search_string =
            'http://www.google.ru/search?num=100&start='.$page.'&q='.$phproxy_sreq;

        my $response = $ua->get($google_search_string);
            die "Error: $response->status_line\n" unless $response->is_success;
        my $source = $response->decoded_content;

        while ($source =~ m#

get($gsstr.$phproxy_sreq); die "Error: $response->status_line\n" unless $response->is_success; my $source = $response->decoded_content; while ($source =~ m#"unescapedUrl":"(http://w{0,3}\.?[\w-]+\.[a-z]{2,4}[/\w-]*/index\.php)\?q#ig) { #push(@$proxy_list, $1); $proxy_list->{$1}++; } } sub SaveResult { #Сохранение результатов проверки списка анонимайзеров my ($options,$proxy_list,$bad_proxy_list) = @_; my ($min, $hour, $day, $month, $year) = (localtime)[1..5]; open(GOOD,'>>',$options->{g}); printf GOOD ( "#Checked: %04d-%02d-%02d %02d:%02d\n", $year+1900, $month+1, $day, $hour, $min ); print GOOD join("\n", keys %$proxy_list); close(GOOD); open(BAD,'>',$options->{b}); printf BAD ( "#Checked: %04d-%02d-%02d %02d:%02d\n", $year+1900, $month+1, $day, $hour, $min ); print BAD join("\n",@$bad_proxy_list); close(BAD); } sub ReadProxyFile { #Считывание списка анонимайзеров из файла my ($options,$proxy_list) = @_; open(PROXY, '<', $options->{i}) or die "Can't open $options->{i}: $!\n"; while() { chomp; s/(#.*|^\s+|\s+$)//; next unless length; #push(@$proxy_list, $_); $proxy_list->{$_}++; } close(PROXY); } sub CheckProxy { #Проверка списка анонимайзеров на валидность с разделением на валидные #и невалидные my ($ua,$proxy_list) = @_; my @bad_proxy; print "\nChecking proxy...\n"; foreach my $proxy_url (keys %$proxy_list) { my $response = $ua->get( $proxy_url.'?q='.encode_base64('http://www.google.com') ); #warn "Error: $response->status_line\n" unless $response->is_success; if ($response->decoded_content =~ m#Google#) { printf ("%-45s %10s", $proxy_url, "\x1b[32m [OK]\x1b[0m\n"); } else { printf ("%-45s %10s", $proxy_url, "\x1b[31m [ERROR]\x1b[0m\n"); push(@bad_proxy, $proxy_url); delete($proxy_list->{$proxy_url}); } } printf ( "Done. Proxy (good | bad): %3d | %-3d\n\n", scalar(keys %$proxy_list), scalar(@bad_proxy) ); return \@bad_proxy; } sub UAInit { #Инициализация "браузера" 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', ); return ($browser); } sub usage { #Вывод справки по использованию программы my $ver = shift; print <