1

我试图登录一个网站,该网站使用此表单和三个输入进行身份验证。

<form action="/login.html" method="post">
<div class="loginlabel1 aright">ID / Email: </div>
<div class="bsearchfield">
<input type="text" name="profid" class="inputBx" size="15" value="" />
</div>
<div class="clear"></div>
<div class="loginlabel1 aright">Password: </div>
<div class="bsearchfield">
<input type="password" name="password" class="inputBx" size="15" value="" />
</div>
<div class="clear"></div>
<div class="loginbutton1">
<input name="login"type="image" src="images/logi.gif" align="right" border="0" />
</div>
</form>

如果我通过浏览器登录,成功登录会将我重定向到http://www.example.com/myhome.html

但是下面的脚本没有让我登录并返回相同的login.html页面。我错过了什么?我没有收到任何错误消息。我发帖成功了吗?

#!/usr/bin/perl -w
use LWP 5.64;
my $browser = LWP::UserAgent->new || die " Failed LWP USER AGENT : $!";
$ENV{HTTP_proxy} = "http://proxy:port";
$browser->env_proxy;
$browser->cookie_jar({});
my @Header    = (
                    'User-Agent'      => 'Mozilla/4.76 [en] (Win98; U)',
                    'Accept'          => 'image/gif, image/x-xbitmap, image/jpeg,image/pjpeg, image/png, */*',
                    'Accept-Charset'  => 'iso-8859-1,*,utf-8',
                    'Accept-Language' => 'en-US',
              );

push @{$browser->requests_redirectable}, 'POST';
$response = $browser->post(
    "http://www.example.com/login.html",
    [
        'profid'   => 'username',
        'password' => 'password'
    ],@Header
);

$response->is_success or die "Failed to post: ", $response->status_line;
print "Successfully posted username and password.\n" if $response->is_fresh;

#printf("%s",$response->content);
printf("%s\n", $response->status_line);
printf("%s",   $response->header("Accept-Ranges"));
printf("%s",   $response->header("Age"));
printf("%s",   $response->header("ETag"));
printf("%s",   $response->header("Location"));
printf("%s",   $response->header("Proxy-Authenticate"));
printf("%s",   $response->header("Retry-After"));
printf("%s",   $response->header("Server"));
printf("%s",   $response->header("Vary"));
printf("%s",   $response->header("WWW-Authenticate"));
delete $ENV{HTTP_PROXY};
4

4 回答 4

2

您的提交按钮是一个图像。单击图像类型的输入时,浏览器会将您单击的像素坐标发送到 CGI。在您的表单中,浏览器会发送login.xandlogin.y以及profidand password

顺便说一句,Firebug是调试 CGI 的好工具。

于 2011-04-08T08:14:45.133 回答
1

有时它们需要正确的接受编码和/或引用标头。可以肯定的是,我也会尝试用户代理标头。

于 2011-04-07T21:11:55.713 回答
0

我还推荐用于 Firefox 的LiveHTTPHeaders 。您打开它,然后提交您的表单,它会准确显示 GET 或 POST 到站点的内容,包括所有标题、参数和 cookie,然后显示来自服务器的所有响应,包括设置的 cookie、标题和重定向.

页面上可能有 javascript 创建额外的参数,当您查看表单时看不到这些参数,图像与 PacoRG 相同,或者它可能要求您首先接受 cookie 并将其与登录一起发送。

LiveHTTPHeaders 还允许您修改标头和“重播” - 这使您可以修改发送到服务器的内容(任何标头、cookie、参数等),以帮助确定服务器实际登录所需的内容。

另外,我相信默认情况下 LWP 会自动跟随重定向,因此页面实际上可能正在重定向而您没有看到它(我相信“simple_request”函数不会跟随重定向。)

在 LWP 响应中,您可以向后遍历任何重定向,如下所示:

my $prev_res = $res->previous();
while ( $prev_res ) {
    print $prev_res->status_line . "\n";
    $prev_res = $prev_res->previous();
}

希望这可以帮助!

于 2011-04-08T11:31:54.610 回答
-1

您没有提交单击的提交按钮的名称;我怀疑另一端的代码正在检查请求中是否存在该变量,以查看表单是否已提交。

正如 PacoRG 指出的那样,提交按钮是一个图像;因此,通过在浏览器中单击该按钮提交将提交名为“login.x”和“login.y”的字段以及“login”。

避免此类问题的一个好方法是使用WWW::Mechanize为您做很多工作,例如:

my $mech = WWW::Mechanize->new;
$mech->get('http://www.example.com/login.html');
$mech-submit_form(
    with_fields => {
        profid => $username,
        password => $password,
    },
);

以上将请求登录页面,找到适当的表单并提交。

此外,正如其他人所说,如果来自脚本的请求与来自浏览器的请求的处理方式不同,那么调试的最佳方法是获取两者都发送的完整 HTTP 请求,并寻找相关的差异。对于浏览器,您可以使用 Firefox 的 LiveHTTPHeaders 或 Tamper Data 插件之类的扩展程序,或者使用 Wireshark 之类的东西在发送请求时捕获请求。对于脚本,您可以轻松地让它输出正在发送的请求。

例如,对于使用 LWP::UserAgent 或 WWW::Mechanize(LWP::UserAgent 的子类)的脚本,您可以添加:

$mech->add_handler("request_send", sub { shift->dump; return });
$mech->add_handler("response_done", sub { shift->dump; return });

这将转储发送的原始请求以及来自服务器的原始响应。(更改$mech为您的 LWP::UserAgent / WWW::Mechanize 对象所在的任何变量 -$browser在您的示例中。)

于 2011-04-08T16:03:43.053 回答