Perl一直号称是黑客语言,事实上也的确是如此。虽然由于工作一直用Python、Tck\tk,但是还是觉得Perl有着无比的吸引力。首先就是看似怪异的语法,渗透着Perl的哲学,同一件事,总有不止一种方法来解决。其实也就是在写法风格上做文章,为了保证人人都能读懂,人人都能调试,人人都能拿过去用,还是老实一些的好。其次就是CPAN上超级多的库,以及Perl本身超级快的执行速度,真的是很吸引人。《程序设计实践》上的那个马可夫链的文本测试我一直记忆犹新,C当仁不让的是最快的,C++其次,然后就是Perl。
应一位写小说的姐姐邀请,这几天抽空用Perl写了一个VoterMan自动打分评论机器人。事实上用Perl强大的网络支持功能完全可以解决任何网站的投票与认证功能,对于基础网站可以使用老牌的LWP,对于一些复杂一些的还是可以用OLE生成IE的COM接口进行处理,或者干脆不用Perl,直接写一个Firefox插件后代执行,当然那就不是本文关心的内容了。
对于自动执行的思路归纳整理如下
- 首先查看自己需要打交道的表单,比如用户名密码表单,评论文本框等等,这个是需要人工看HTML代码的,无法让机器代劳。
- 其次就是判断有哪些东西组织我们进行自动化提交表单,比如是否有认证码,或者时间、IP、内容长度限制。
- 然后就是针对网站的限制,首先测试一些解决方案,比如是否能够OCR出认证码,设置多长的时间间隔,预先写好填充内容等。
- 如何判断结束,获得我们想要的内容。
对于有内容长度限制的,我们可以事先写一些评论。对于限制IP的,比如投票,我们完全可以让机器不断的自动拨号,投票后断线的方式进行,或者是自动搜索世界范围内的代理服务器进行连接,比如Your Freedom就是这个样子,基本上想逆向追查是不太可能的。对于有注册码的,需要预先选择强壮的OCR模块,由Perl自动调用进行图片解析。对于银行信用卡这样的,尤其是招行一卡通大众版,由于它使用HTTPS连接,而且需要安装它的插件,所以还是只能用OLE进行处理,通过操作IE进行密码猜解。它的验证码实在是很简单,甚至不像CSDN那样的复杂。但是由于是慢速连接,可能速度不理想,不过可以开10个线程一直让它猜解么,反正我们人又不累哈哈。
附上代码,有修改,不能泄漏了俺姐姐的机密嘿嘿。本代码适合那个网站的任何小说。事先需要准备两个文本,一个储存虚拟评论员(或者叫做5毛)的名称和可用的代理服务器,另外一个储存评论文本,多多益善。至于随机部分大家可以自由发挥以达到人肉都无法判断真假的效果。推荐使用Perl2EXE生成EXE文件,直接在没有安装Perl的机器上执行。
Code
#Copyright 2008 Bo Schwarzstein
#注意文本字符编码格式,推荐使用ASCII而不是Unicode
use strict;
use LWP::UserAgent::ProxyAny;
use LWP::UserAgent;
#生成非重复的随机序列用于随机章节数目
#为了效率而使用简单的轮换而没有用拒绝采样法
sub GetNonRepeatSeq
{
my $startnum = $_[0];
my $endnum = $_[1];
my @seq;
for( my $i = $startnum; $i < $endnum+1; $i++)
{
@seq[$i] = $i;
}
my $swaptime = int( $endnum * 0.75 );
for( my $j = 0; $j < $swaptime; $j++ )
{
my $a = int( rand(16) );
my $b = $a;
while( $a == $b )
{
$b = int( rand(16) );
}
my $temp = @seq[$a];
@seq[$a] = @seq[$b];
@seq[$b] = $temp;
}
return @seq;
}
#读取评论数据
open( ComHandle, "< E:/Comment.txt" )
or die "Can't Find Comments Data\n";
my @CommentsArray;
my $N = 0;
while( <ComHandle> )
{
chop;
@CommentsArray[$N] = $_;
$N++;
}
close ComHandle;
#读取作者IP数据
open( AutHandle, "< E:/Author.txt" )
or die "Can't Find Authors Data\n";
my @AuthorsArray;
my @ProxyArray;
$N = 0;
while( <AutHandle> )
{
chop;
my @items = split / /;
@AuthorsArray[$N] = @items[0];
@ProxyArray[$N] = @items[1];
$N++;
}
close AutHandle;
my $UserAgent = LWP::UserAgent::ProxyAny->new;
my $NovelID = xxxxxx;#这里是你的小说ID
my $StartChapID = 1;
my $EndChapID = 9999999;
my $baseurl = 'http://www.jjwxc.net/onebook.php?';
my @ChapterSeq = GetNonRepeatSeq($StartChapID,$EndChapID);
my @ComSeq = GetNonRepeatSeq(1,20);
for(my $chapterid = $StartChapID; $chapterid <= $EndChapID; $chapterid++ )
{
my $fullurl = $baseurl."novelid=".$NovelID."&"."chapterid=".$chapterid;
print "Working On This URL : ".$fullurl."\n";
my $resp = $UserAgent->get($fullurl);
if( $resp->is_success )
{
use HTML::Form;
my @forms = HTML::Form->parse($resp->content, $resp->base);
my $form = @forms[3];
my $n = 2;
print "Author : ".@AuthorsArray[$n]."\n";
$form->value("commentauthor",@AuthorsArray[$n]);
$form->value("commentmark",5);
my $k = int( scalar(@CommentsArray) * rand(1.0) );
#print @CommentsArray[$n]."\n";
print "Comment : ".@CommentsArray[ @ComSeq[$chapterid] ]."\n";
$form->value("commentbody",@CommentsArray[ @ComSeq[$chapterid] ]);
my $commentreq = $form->click("button1");
my $proxyurl = "http://".@ProxyArray[$n];
print "Proxy : ".$proxyurl."\n";
$UserAgent->proxy( [qw(http https)] => $proxyurl );
my $badresp = $UserAgent->request($commentreq);
if( $badresp->is_success )
{
print "Finish Voting For Chapter ".$chapterid."\n";
sleep 120 + sin(rand(3.1419926 / 2.0))*10;#设置下一次投票间隔,随机增加10秒偏移
}
}else
{
print "From Chapter [".$chapterid."] Response Error!\n";
die $resp->status_line;
}
}
就本程序来说,稍加更改破解诸如西祠胡同、校内网的密码根本不是任何问题,本人一心向善,这些歪门邪道的应用恕不完成。