Chinaunix

标题: perl小程序--登录含验证码的站点 [打印本页]

作者: ykredrum    时间: 2013-01-25 02:10
标题: perl小程序--登录含验证码的站点
本帖最后由 ykredrum 于 2013-01-25 02:10 编辑

很久没有发过贴了,睡不着起来发一个,lwp是个好模块,上网站自动完成点任务多方便的,不过很多操作都需要在你正确登录网站的前提下才能进行,登录一个没有验证码的网站还挺容易的,如果登录的时候要求你输入验证码就比较麻烦,你可以改cookie,但是如果每次登录账号不一样感觉比较麻烦,个人写了个小程序,登录的时候程序先自动将验证码图片下载下来,等人工识别然后人工输入,程序接受输入后再继续登录。 虽然麻烦点,不过还是算一种方法吧。

程序概述:

  1.程序根据特定的网站写的,所以大家就看看大概原理就是了,照搬到其他网站肯定不成功。

  2.大概原理,页面得到验证码是通过一个特定的链接,登录的时候直接通过这个链接得到验证码,然后加到账户信息里面post出去,登录就成功了。

代码如下:

  1. use strict;
  2. use warnings;
  3. use LWP;
  4. use LWP::ConnCache;


  5. # main procedure #
  6. my $ua = LWP::UserAgent->new( );
  7. # setup attribution #
  8. push @{ $ua->requests_redirectable }, 'POST'; # post之后能自动打开redirect页面
  9. $ua->agent('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; EmbeddedWB 14.52 from: http://www.bsalsa.com/ EmbeddedWB 14.52; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; AskTbFXTV5/5.11.3.15590)');
  10. $ua->cookie_jar( {} );  #打开cookie功能
  11. $ua->timeout(15);
  12. $ua->conn_cache( LWP::ConnCache->new() ); # keep alive

  13. if( &login ){
  14.     print "登录成功!\n";
  15. }else{
  16.     print "登录失败!\n";
  17. }


  18. sub login {
  19.     my $acc = shift || '这里填默认使用的账号';
  20.     my $pw  = shift || '这里填默认使用的密码';

  21.     my $response = $ua->get('http://www.xckjpx.net/user/login_inc/checkcode/checkcode.asp');

  22.     if ($response->is_success) {

  23.         # 抓取验证码图片 #
  24.         open my $check_code_image, "> verifycode.BMP"  #默认验证图片的位置在当前目录
  25.                 or die "$!";

  26.         binmode($check_code_image);
  27.         print $check_code_image $response->content;
  28.         close $check_code_image; #关闭print对句柄的控制

  29.         { # 输入验证码并登录 #

  30.           print "> enter verifycode:";
  31.           chomp( my $verifycode = <> );
  32.           $verifycode=~ s/\s//g; #删除空白

  33.           my $response = $ua->post(
  34.                                  'http://www.xckjpx.net/user/check.asp',
  35.                                  [username => $acc, password => $pw, xhccl => 'login', verifycode => $verifycode, Sub_sub =>''],
  36.                                   );

  37.           if ($response->is_success) {

  38.               return $response->content =~ /location='login.asp'/ ? 0 : 1;  # 根据是否重定向页面到登录界面来判断登录是否成功
  39.                                                                             # 登录成功返回 1     登录失败返回 0
  40.           }
  41.           else {
  42.               print '> failed to post data for login:  ' . $response->status_line . "\n";
  43.           }
  44.         } #

  45.     }
  46.     else {
  47.          print '> failed to get verifycode:  ' . $response->status_line . "\n";
  48.     }

  49. }
复制代码
最后:
程序里本来有个默认账号和密码,因为不是我自己的,不敢泄露别人隐私,大家就自己申请一个吧
login函数不填参数就使用默认账号和密码。

上面程序有正确账号和密码的话是能成功登录的,发帖前测试过。
作者: bikong0411    时间: 2013-01-25 08:58
我怎么觉得不靠谱呢,你得到验证码,然后再去请求时验证码已经变了:wink:
作者: kernel69    时间: 2013-01-25 10:21
想研究一下,收了
作者: ykredrum    时间: 2013-01-25 11:56
本帖最后由 ykredrum 于 2013-01-25 11:57 编辑
bikong0411 发表于 2013-01-25 08:58
我怎么觉得不靠谱呢,你得到验证码,然后再去请求时验证码已经变了



你说的这个问题我考虑了的,程序里只get一次验证码的链接,就是说,验证码就没有改变过

而且上面的小程序测试成功了我才帖出来的,呵呵。
   
作者: ttcn_cu    时间: 2013-01-25 12:48
我记得有个项目里验证码是用 xdg-open 打开的,处理的比较好
作者: ykredrum    时间: 2013-01-25 13:14
本帖最后由 ykredrum 于 2013-01-25 13:52 编辑
ttcn_cu 发表于 2013-01-25 12:48
我记得有个项目里验证码是用 xdg-open 打开的,处理的比较好


谢谢,刚才去看了看, xdg-open 确实是个好东西,以前我不知道,又学习了,thx

不过Windows下 xdg-open 不能用.
作者: ludio333    时间: 2013-01-25 15:36
简单验证码字母和数字加噪点等可以用Image::Magick识别
汉字和扭曲严重的就没想到什么好办法了
作者: iakuf    时间: 2013-01-25 16:42
这个太复杂,使用 Mojo::UserAgent 可以做到只有这个 1/6 的代码
作者: hunter_cao    时间: 2013-01-26 23:39
我去试试这个看看Image::Magick
作者: ykredrum    时间: 2013-02-02 19:20
好的,发个帖子,知道很多没有用过的模块,谢谢大家
作者: freedos520    时间: 2013-02-05 14:41
谢谢,试试再说!
作者: dahe_1984    时间: 2013-02-06 22:16
看看,正需要这方面的东东呢
作者: dahe_1984    时间: 2013-02-18 14:50
use strict;

use warnings;

use LWP;

use LWP::ConnCache;



# main procedure #

my $ua = LWP::UserAgent->new( );

# setup attribution #

push @{ $ua->requests_redirectable }, 'POST'; # post之后能自动打开redirect页面

$ua->agent('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; EmbeddedWB 14.52 from: http://www.bsalsa.com/ EmbeddedWB 14.52; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; AskTbFXTV5/5.11.3.15590)');

$ua->cookie_jar( {} );  #打开cookie功能

$ua->timeout(15);

$ua->conn_cache( LWP::ConnCache->new() ); # keep alive


if( &login ){

    print "登录成功!\n";

}else{

    print "登录失败!\n";

}



sub login {

    my $acc = shift || '这里填默认使用的账号';

    my $pw  = shift || '这里填默认使用的密码';
    my $verifycode;


    my $response = $ua->get('http://www.xckjpx.net/user/login_inc/checkcode/checkcode.asp');


    if ($response->is_success) {


        # 抓取验证码图片 #

        open my $check_code_image, "> verifycode.BMP"  #默认验证图片的位置在当前目录

                or die "$!";


        binmode($check_code_image);

        print $check_code_image $response->content;

        close $check_code_image; #关闭print对句柄的控制


        { # 输入验证码并登录 #

        my $pid = fork();
        if ($pid) {
        # parent
        
          print "> enter verifycode:";

          chomp( $verifycode = <> );

          $verifycode=~ s/\s//g; #删除空白

        } elsif ($pid == 0) {
                # child
                sleep 10;
                `mspaint verifycode.BMP`;
                exit 0;
        } else {
                die "couldnt fork: $!\n";
        }

        waitpid($pid,0);

          my $response = $ua->post(

                                 'http://www.xckjpx.net/user/check.asp',

                                 [username => $acc, password => $pw, xhccl => 'login', verifycode => $verifycode, Sub_sub =>''],

                                  );


          if ($response->is_success) {


              return $response->content =~ /location='login.asp'/ ? 0 : 1;  # 根据是否重定向页面到登录界面来判断登录是否成功

                                                                            # 登录成功返回 1     登录失败返回 0

          }

          else {

              print '> failed to post data for login:  ' . $response->status_line . "\n";

          }

        } #


    }

    else {

         print '> failed to get verifycode:  ' . $response->status_line . "\n";

    }


}

加个自动打开图片的功能,免得还要自己找图片
作者: lxb456811    时间: 2013-02-18 16:34
    很好很强大
作者: hunter_search    时间: 2013-02-19 16:55
还以为有验证码识别呢,原来是手工输入呢
作者: melanie0202    时间: 2014-01-08 15:54
感觉这个功能不错,先收了
作者: fender0107401    时间: 2014-01-08 16:48
关键的问题是如何识别验证码,其他的都好说。
作者: fender0107401    时间: 2014-01-08 16:49
要机器识别的,不能是人去识别。
作者: jzp520520    时间: 2014-01-17 23:26
回复 1# ykredrum
程序逻辑有点小错误:
---------- perl ----------
Use of uninitialized value $verifycode in chomp at LWP1.pl line 75.
Use of uninitialized value $verifycode in substitution (s///) at LWP1.pl line 77.
> enter verifycode:登录成功!

在没有输入验证码的情况下,也显示了“登录成功”!
由于刚学习你的代码,不太懂,所以不知怎么改!
大神,解决一下!


   
作者: ykredrum    时间: 2014-02-05 22:24
回复 19# jzp520520
这小段程序只是提供个思路,这个不能通用的,具体网站要具体分析。


   
作者: ykredrum    时间: 2014-02-05 22:28
dahe_1984 发表于 2013-02-18 14:50
use strict;

use warnings;

这个不错,呵呵!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2