perl+LWP包使用的问题,也说说我对perl的疑惑.



QUOTE:
原帖由 NewCore 于 2007-8-29 17:21 发表
选择用perl主要出于两个原因,1是它是脚本语言,可以和应用程序分离,2是它资源多,开发快。对于我一个半生不熟的perler来说,确实暂时还没有体会到第2这个优点。但是出于项目整体的角度,我还是选择用perl来做 ...

对于2,多查查cpan
说的是,有问题还得多多请教。


QUOTE:
原帖由 NewCore 于 2007-8-29 17:43 发表
说的是,有问题还得多多请教。

wel
使用163邮箱测试,目的1是练练手,为后面项目开展做准备;2是熟悉使用perl进行网页交互这一块。

程序基本上完成,只能算一个简单测试,发上来,欢迎大家多拍拍

总感觉自己写的perl中还是有c的影子,呵呵,旧习难改咯。

[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/perl                                                                    
                                                                                   
use strict;                                                                        
use LWP::UserAgent;                                                               
use HTML::Form;                                                                    
                                                                                   
my $url = "http://www.163.com";                                                   
                                                                                   
my $ua = new LWP::UserAgent(cookie_jar => {});                                    
my $res = $ua->get($url);                                                         
unless($res->is_success()) {                                                      
    print "cannot get content from", $url, "\n";                                   
    return;                                                                        
}                                                                                 
                                                                                   
my @forms = HTML::Form->parse($res->content(), $url);                              
                                                                                   
# enumerate every form in forms                                                   
foreach my $form (@forms) {                                                        
    if($form->find_input(undef, "submit") &&                                       
        $form->find_input("username") &&                                          
        $form->find_input("password")) {                                          
        print $form->dump();                                                      
        # ok, we will click button to submit our request.                          
        $form->value("username", "newcore22");                                    
        $form->value("password", "pwd");   
        # see if value of input boxes have been modified.                          
        print $form->dump();                                                      
                                                                                   
        # cuase form->click($name) method requires a parameter of control's name,  
        # but login button has no name. we use form->make_request() instead.      
#        $form->click("submit");                                                   
        my $req = $form->make_request();                                          
        # fire login request                                                      
        my $res2 = $ua->request($req);         
                                    
        # see what wo got from http server     
         if($res2->is_success()) {                                          
             print "\nlogin response from http server\n";                    
             print $res2->content();                                         
             # write to file                                                
             open fd, ">./web.html" || die "open file failed\n";            
             print fd $res2->content();                                      
             close fd;                                                      
         }                                                                  
         else {                                                              
             print "\nlogin failed with error ", $res2->status_line(), "\n";
         }                                                                  
         goto out;                                                           
     }                                                                       
     else {                                                                  
         print "fail to submit\n"                                            
     }                                                                       
}                                                                           
out:                                                                        
print "exit normally\n";                                                                                                     

1、

[Copy to clipboard] [ - ]
CODE:
$form->find_input(undef, "submit");

呵呵,也不知道这样写在perl里是否标准。因为不知道第一个参数name,所以我就用undef了。或者还有其他写法?

2、

[Copy to clipboard] [ - ]
CODE:
my $res2 = $ua->request($req);   

这里,我不太确定是否可以直接用$res = $ua->request($req);,因为不确定perl中对变量内存的管理。我的意思是:下面这样写,是否会造成内存的泄漏问题?

[Copy to clipboard] [ - ]
CODE:
$res = $ua->request($req); or
$res=undef;
$res=$ua->request($req); or
要释放$res的内存先?

呵呵,估计这种问题在c版出现机率比较大,不过还是希望能有人澄清一下。

3、perl代码给我最大的感觉就是:简洁。这可能和其他多数语言的特点都不太一样。当然,它的简洁是建立在对语法很熟悉的基础上,对于一个c程序员来说,这种转变还不是一件容易地的事。 见笑了



QUOTE:
  if($form->find_input(undef, "submit") &&                                       
        $form->find_input("username") &&                                          
        $form->find_input("password"))

上面的代码是为了找到所要的form吧?这样是不是太臃肿了?看看网页的html,就可以看到要登录的from的id是login:

QUOTE:

my @forms = HTML::Form->parse($res->content(), $url);   
@forms = grep $_->attr("id") eq "login", @forms;
die "No form named 'login' found" unless @forms;
$form = shift @forms;
下面继续

你说的很有道理。
按照你给的方式修改了一下,提示错误如下:
Can't locate object method "attr" via package "HTML::Form" at ./web2.pl line 19.
是不是我的HTML::Form模块需要更新一下?
我没有遇到这个问题……
我正在写一个处理163信箱的程序。

可是无论使用14楼的代码,还是使用Mechanize模块,都登录有问题。

如果填写密码正确,163网站会提示“很遗憾 ”
如果填写密码错误,163网站会提示“对不起,您的密码不正确!”

请问登录失败的原因在哪里?
谢谢!