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

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

目的是实现对web页面的内容进行分析,代码列举如下:

[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/perl

use LWP::UserAgent;
use HTML::Form;

my $ua = new LWP::UserAgent(cookie_jar => {});
my $res = $ua->get('http://www.163.com');

# 1. 这里是获得当前网页中所有的form,如何在返回的forms里枚举所有的form,取出我要操作的那个form?
my $forms = HTML::Form->parse($res->content(), 'http://www.163.com');

# 2. 参考perldoc,如下调用返回forms的所有input元素。既然forms里面包含多个form,这里的forms又是哪一个?
my $inputs = $forms->inputs();

# 3. 下面就纯粹是测试用了,但是执行时提示错误:
# Can't call method "type" without a package or object reference, my $inputs = $forms->inputs();-〉inputs是这里的返回值啊

if($inputs->type eq "submit") {
    print "get submit type\n";
}
else {
    print "no submit type\n";
}
print "exit normally\n";

上面代码中的1,2,3处是我有问题的地方,请指教。

下面是我的疑惑,请澄清:
1。说实话,看perldoc看的比较郁闷,对于函数的参数和返回值由于缺少强类型语言的类型检查,同时,
引用的引入更增加了理解的难度。为了查某个函数参数和返回值,结果却是看了perldoc还是不太明白它
的返回值是什么。具体来说,如2:

2。看看函数参数,却更觉得迷惑。
如上这个例子:my $forms = HTML::Form->parse($res->content(), 'http://www.163.com');
$res->content()里应该就包含了整个网页的内容了吧,干嘛还要个uri参数?(perldoc里的函数原形为
@forms = HTML::Form->parse($html_document, $base_uri);
这个uri参数在这里不就是一个perl里的标量字符串吗,而第二个参数$base_uri这样的形式是可以接受任
意类型的参数了,我要传个array或者hash进去也OK,我真想知道函数的实现者在无类型判断的情况下,
如何实现如此功能,估计也挺累的...)

基本上如上面所说,这个功能是我从项目里抠出来,特别考虑用perl来实现的,希望能够澄清一些问题,
否则工作效率太低了。
请大家不吝赐教,更希望你留下宝贵的经验。

perldoc 部分摘录(注意红色部分):

QUOTE:
@forms = HTML::Form->parse( $response )
@forms = HTML::Form->parse( $html_document, $base )
@forms = HTML::Form->parse( $html_document, %opt )
    The parse() class method will parse an HTML document and build up
    "HTML::Form" objects for each <form> element found. If called in
    scalar context only returns the first <form>. Returns an empty list
    if there are no forms to be found.

    The $base is the URI used to retrieve the $html_document. It is
    needed to resolve relative action URIs. If the document was
    retrieved with LWP then this this parameter is obtained from the
    $response->base() method, as shown by the following example:

        my $ua = LWP::UserAgent->new;
        my $response = $ua->get("http://www.example.com/form.html");
        my @forms = HTML::Form->parse($response->decoded_content,
                                      $response->base);
......

@inputs = $form->inputs
    This method returns the list of inputs in the form. If called in
    scalar context it returns the number of inputs contained in the
    form. See "INPUTS" for what methods are available for the input
    objects returned.
.....

下面回答你提出的问题:

# 1. 这里是获得当前网页中所有的form,如何在返回的forms里枚举所有的form,取出我要操作的那个form?
my $forms = HTML::Form->parse($res->content(), 'http://www.163.com');
# 2. 参考perldoc,如下调用返回forms的所有input元素。既然forms里面包含多个form,这里的forms又是哪一个?
my $inputs = $forms->inputs();
[flw]: HTML::Form->parse 返回的是一个列表,你可以用一个数组来接受该列表的所有元素。
# 3. 下面就纯粹是测试用了,但是执行时提示错误:
# Can't call method "type" without a package or object reference, my $inputs = $forms->inputs();-〉inputs是这里的返回值啊
[flw]: 按 perldoc,你用 my $inputs = 接收到的是 input 控件的个数,而不是控件对象本身。
如上这个例子:my $forms = HTML::Form->parse($res->content(), 'http://www.163.com');
$res->content()里应该就包含了整个网页的内容了吧,干嘛还要个uri参数?
[flw]: $base 的作用,是为了决定使用相对路径描述的链接的地址。
I 服le U!你口口声声说文档,你到底看了文档没有???

QUOTE:
原帖由 NewCore 于 2007-8-29 16:11 发表
目的是实现对web页面的内容进行分析,代码列举如下:

QUOTE:
#!/usr/bin/perl

use LWP::UserAgent;
use HTML::Form;

my $ua = new LWP::UserAgent(cookie_jar => {});
my $res = $ua->get('http://www.163.com');

# 1. 这里是获得当前网页中所有的form,如何在返回的forms里枚举所有的form,取出我要操作的那个form?
# 你既然知道获得所有的form,为何用$form而不是@form? 既然用$form,就应该明白文档中说的:If called in scalar context only returns the first <form>.
my $forms = HTML::Form->parse($res->content(), 'http://www.163.com');

# 2. 参考perldoc,如下调用返回forms的所有input元素。既然forms里面包含多个form,这里的forms又是哪一个?
my $inputs = $forms->inputs(); #同样: If called in scalar context it returns the number of inputs contained in the form. 返回的是inputs的个数,如果想避免你下面提到的错误,可以用:
my ($inputs) = $forms->inputs(); #得到第一个inputs

# 3. 下面就纯粹是测试用了,但是执行时提示错误:
# Can't call method "type" without a package or object reference, my $inputs = $forms->inputs();-〉inputs是这里的返回值啊
# 既然测试,为什么不print $inputs看看?

if($inputs->type eq "submit") {
    print "get submit type\n";
}
else {
    print "no submit type\n";
}
print "exit normally\n";


被版主抢前面了


QUOTE:
原帖由 royalzhang 于 2007-8-29 17:05 发表
被版主抢前面了

不好意思。
LS说的是,是我看得不仔细了

第一次用perl做项目,碰到一些问题,有点发晕...见笑见笑了。归根结底,还是自己对perl掌握不扎实,不过本意也是想趁这个机会,把perl给学习一下。
再给楼主推荐一个很好用的内建模块:

perldoc Data::Dumper

我在使用陌生模块时,经常用它。


QUOTE:
原帖由 flw 于 2007-8-29 17:13 发表
再给楼主推荐一个很好用的内建模块:

perldoc Data:umper

我在使用陌生模块时,经常用它。

收到。眼熟,看到有人用过。多谢推荐。


QUOTE:
原帖由 NewCore 于 2007-8-29 17:12 发表
LS说的是,是我看得不仔细了

第一次用perl做项目,碰到一些问题,有点发晕...见笑见笑了。归根结底,还是自己对perl掌握不扎实,不过本意也是想趁这个机会,把perl给学习一下。

Perl 不好用的名声都是半瓶水们给传扬出去的。
一种技术太平易近人了总不是件好事,
如果像 C 语言那样光编译过去就要费好大劲,
稍微写得不对点儿就是段错误,
那我们现在看到的 Perl 程序的质量会好多。
选择用perl主要出于两个原因,1是它是脚本语言,可以和应用程序分离,2是它资源多,开发快。对于我一个半生不熟的perler来说,确实暂时还没有体会到第2这个优点。但是出于项目整体的角度,我还是选择用perl来做。而且,我相信跨过这个障碍,应该会有不一样的情况。