Самая эффективная защита от парсинга
Самая эффективная зашита от парсинга (то есть защита от парсинга — я кстати вылез в топ гугл по запросу этому) — у сайта film.ru . Они просто отключили сайт когда я их начал парсить.
Развожу руками.
Самая эффективная зашита от парсинга (то есть защита от парсинга — я кстати вылез в топ гугл по запросу этому) — у сайта film.ru . Они просто отключили сайт когда я их начал парсить.
Развожу руками.
Копал-копал и нашёл как сделать Google Maps статичной картинкой.
Поддерживается до 640×640, формат — .gif
Ссылка вида http://maps.google.com/staticmap?center=Координаты&zoom=Зум&size=ШиринаxВысота&markers=Координаты маркера по желанию
Хозяйке на заметку:
Два+ пробела заменяются не так:
perl -le ‘use Data::Dumper; my $x = «abc bca \n \t abc bca»; $x =~ s/\s{2,}/ /g; print Dumper $x’
$VAR1 = ‘abc bca abc bca’;
Два+ пробела заменяются так:
perl -le ‘use Data::Dumper; my $x = «abc bca \n \t abc bca»; $x =~ s/[[:blank:]]{2,}/ /g; print Dumper $x’
$VAR1 = ‘abc bca
abc bca’;
#! /usr/bin/perl -w
use strict;
use Socket;my $port = shift || 82;
my $proto = getprotobyname(‘tcp’);socket(SERVER, PF_INET, SOCK_STREAM, $proto) or die «socket: $!»;
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1) or die «setsock: $!»;my $paddr = sockaddr_in($port, INADDR_ANY);
bind(SERVER, $paddr) or die «Failed bind: $!»;
listen(SERVER, SOMAXCONN) or die «Failed listen: $!»;
print «Daemon started on port $port «;my $client_addr;
while ($client_addr = accept(CLIENT, SERVER)){my ($client_port, $client_ip) = sockaddr_in($client_addr);
my $client_ipnum = inet_ntoa($client_ip);
#my $client_host = gethostbyaddr($client_ip, AF_INET);
print «got a connection from: [$client_ipnum] \n»;
print CLIENT «IP $client_ipnum $client_port\n\n»;
close CLIENT;
}
#!/usr/bin/perl -w
use strict;
use Term::ANSIColor;
use Time::HiRes qw[usleep];
if(defined($ARGV[0]) && $ARGV[0]!~/^\d+$/){
print color ‘reset’;
exit;
}
my $num = 2000; # сколько раз крутить
my $strlen = 20; # длина строки
my $length = 10000; # чем больше — тем дольше будет «вычисляться» строка$num = $ARGV[0] if $ARGV[0] =~ /^\d+$/;
$strlen = $ARGV[1] if $ARGV[1] =~ /^\d+$/;
$length = $ARGV[2] if $ARGV[2] =~ /^\d+$/;
my ($stop, %test) = (0);
my @a = (‘a’..’z’, ‘A’..’Z’, 0..9);
for(0..$num){
for(0..$strlen){
my $s = $a[int(rand($#a+1))];
print color ‘bold green’;
if(exists($test{$_})){
print color ‘clear green’;
print $test{$_};
}
else{
print $s;
$test{$_} = $s if(int(rand($length)) == ($length-1));
}
print q[ ];
print color ‘reset’;
}
usleep(rand(10000)+10000);
print «\n»;
last if $stop > 0;
$stop ++ if scalar keys %test == ($strlen+1);
}
print color ‘reset’;
Для одной мерзкой цели потребовалось ходить в ЖЖ через HTTP — так удобней парсить некоторые вещи.
Собственно, сниппет под катом.
Пара слов о куках. Мне стало уже лениво писать под них лишние регулярки — но список их следующий:
- ljuniq
- ljmastersession
- ljloggedin
- BMLschemepref (схема кстати — кому хочется обратно dystopia — просто смените эту куку)
- langpref
- ljsession
- ljdomsess.{username} — у меня, соответственно, ljdomsess.skazo4nik
Берём поисковый таймлайн по слову, к примеру, ru_followfriday и френдим всех кого ещё не френдим. В минуту в среднем можно делать 2-3 запроса — поэтому спим с рандомчиком.
#!/usr/bin/perl -w
use strict;
use WWW::Curl::Easy;my $login = q[skazkin];
my $password = q[];my $href = qq[http://search.twitter.com/search.atom?lang=en&q=ru_followfriday&rpp=100];
my $result = callTwitter({href=>$href});
my (@toFollow, $followed);
if($result->{content}){
while($result->{content} =~ /@([a-z0-9_]+)/ig){
my $name = $1;
while(1){
$followed = callTwitter({href=>qq[http://twitter.com/friendships/show.xml?source_screen_name=$name&target_screen_name=$login]});
if($followed->{content}=~/150 requests/){
print qq[Rate limit exceeded — sleep for one hour.\n];
sleep(3600);
}
last;
}
sleep(25+rand(5));
$followed->{content} =~ s/\n//g;
my $following_status = q[];
$following_status = $1 if $followed->{content} =~ /$login.*? ([^<]+)<\/following>/i;
print $name.» — «.$following_status.»\n»;
push(@toFollow,$name) if $following_status eq q[false];
}
print qq[Ready to follow ].($#toFollow+1).qq[ pupils\n];
foreach(@toFollow){
print qq[Following $_\n];
callTwitter({href=>qq[http://twitter.com/friendships/create/$_.xml?follow=true],post=>1});
sleep(25+rand(5));
}
}sub callTwitter {
my $params = shift;
my ($result, $retcode, $curl) = (‘false’,undef,undef);
$curl = new WWW::Curl::Easy;
$curl->setopt(CURLOPT_URL, $params->{href});
$curl->setopt(CURLOPT_USERPWD, $login.q[:].$password);
$curl->setopt(CURLOPT_POST, 1) if $params->{post};
$curl->setopt(CURLOPT_POSTFIELDS, $params->{post}) if ($params->{post} && $params->{post}=~/=/);
open (my $tmp_for_curl, «>», \$result);
$curl->setopt(CURLOPT_FILE,$tmp_for_curl);
$retcode = $curl->perform;
return {retcode => $retcode, content => $result};
}
Ещё не проверял — пока тестил — выбрал 150 часовых запросов.
#!/usr/bin/perl -w
use strict;
use Digest::MD5 qw(md5_hex);
use WWW::Curl::Easy;
use URI::Escape;
use Carp qw[croak];
use Text::Iconv;my $twitter_login = q[skazkin];
my $twitter_password = q[];my $vkontakte_login = q[e@mail];
my $vkontakte_password = q[];my $tmp_file = q[/tmp/v2t.tmp];
my $converter = Text::Iconv->new(q[windows-1251], qq[UTF8]);
my $check_hash = q[];
if(-e $tmp_file){
open FF, qq[<$tmp_file]; $check_hash =;
close FF;
}
my $data = getURL(
{
href => q[http://vkontakte.ru/login.php],
referer => q[http://vkontakte.ru/index.php],
headers_list => [
‘Content-Type: application/x-www-form-urlencoded; charset=UTF-8’,
‘X-Requested-With: XMLHttpRequest’,
‘Cookie: remixlang=0; remixchk=5’
],
post => qq[op=a_login_attempt&email=$vkontakte_login&pass=$vkontakte_password&expire=0]
}
);
my ($id, @cookies, $status);
$id = $1 if $data->{content} =~ /good(\d+)/;
croak q[Can not login!\n] if !$id;
while($data->{content} =~ /set\-cookie:([^;]+)/ig){
push(@cookies,$1);
}
croak q[No cookies] if $#cookies == -1;
$data = getURL(
{
href => qq[http://vkontakte.ru/id$id],
cookie => join(«;»,@cookies)
}
);
$status = $1 if $data->{content} =~ /activity_editor\.setup\(«([^»]+)»\)/i;
croak q[No status!\n] if !$status;
croak q[Length exceed!\n] if length $status > 140;
if(md5_hex($status) ne $check_hash){
open FF,»>$tmp_file»;
print FF md5_hex($status);
close FF;
$status = $converter->convert($status);
$data = getURL(
{
href => q[http://twitter.com/statuses/update.xml],
post => q[status=].uri_escape($status),
user_auth => qq[$twitter_login:$twitter_password]
}
);
print qq[http://twitter.com/$twitter_login/status/$1\n] if $data->{content} =~ /(\d+)/;
exit;
}
else{
print qq[Similar status!\n];
exit;
}
print qq[Cannot post to twitter!\n];
sub getURL {
my $params = shift;
my ($result, $retcode, $curl) = (‘false’,undef,undef);
$curl = new WWW::Curl::Easy;
$curl->setopt(CURLOPT_URL, $params->{href});
$curl->setopt(CURLOPT_USERAGENT, q[Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2]);
$curl->setopt(CURLOPT_USERPWD, $params->{user_auth}) if $params->{user_auth};
$curl->setopt(CURLOPT_HTTPHEADER, $params->{headers_list}) if $params->{headers_list};
$curl->setopt(CURLOPT_REFERER, $params->{referer}) if $params->{referer};
$curl->setopt(CURLOPT_FOLLOWLOCATION,1);
$curl->setopt(CURLOPT_HEADER, 1);
$curl->setopt(CURLOPT_COOKIE, $params->{cookie}) if $params->{cookie};
$curl->setopt(CURLOPT_POST, 1) if $params->{post};
$curl->setopt(CURLOPT_POSTFIELDS, $params->{post}) if $params->{post};
open (my $tmp_for_curl, «>», \$result);
$curl->setopt(CURLOPT_FILE,$tmp_for_curl);
$retcode = $curl->perform;
return {retcode => $retcode, content => $result};
}
Вызывается с параметром тег [сколько записей смотреть на предмет твиттерчан, по умолчанию 100]
Типа
perl script.pl followfriday 80
— пролистает 80 последних записей ленты и вычленит из них все встречающиеся ники, которые потом поделит на посты до 140 символов.
Запись в кроне, соответственно —
# пятница
10 16 * * 5 perl script.pl followfriday
# понедельник
10 16 * * 1 perl script.pl sexymonday
# среда
10 16 * * 3 perl script.pl tinyfriday
Предположим, что сегодня — 31 августа.
<script type=»text/javascript»>
var d=new Date();
d.setUTCMonth(0);
document.write(d);</script>
Логично предположить что это выдаст январь.
Попробуем
<script type=»text/javascript»>
var d=new Date();
d.setUTCMonth(1);
document.write(d);</script>
Казалось бы — февраль? А нет, на дворе март.
Играемся со втормы параметром.
<script type=»text/javascript»>
var d=new Date();
d.setUTCMonth(1,0);
document.write(d);</script>
Вот и январь опять вернулся.
<script type=»text/javascript»>
var d=new Date();
d.setUTCMonth(1,1);
document.write(d);
</script>
А это уже — первое февраля.
Удивительное рядом — второй параметр по дефолту принимает текущий день! Так что дату надо ставить принудительно!