我试图登录使用此表单的网站,其中包含三个输入进行身份验证。
<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};
答案 0 :(得分:2)
您的提交按钮是一张图片。单击类型图像的输入时,浏览器会将您单击的像素坐标发送到CGI。在您的表单中,浏览器会发送login.x
和login.y
以及profid
和password
。
BTW,Firebug是调试CGI的绝佳工具。
答案 1 :(得分:1)
有时它们需要正确的accept-encoding和/或referer标头。我还会尝试使用user-agent标头。
答案 2 :(得分:0)
我还建议Firefox使用LiveHTTPHeaders。你打开它,然后提交你的表单,它显示GET或POST到网站的确切内容,包括所有标题,参数和cookie,然后显示来自服务器的所有响应,包括设置cookie,标题和重定向
页面上可能有javascript会创建额外的参数,当您只是查看表单时,您没有看到这些参数,上面描述的图像编码为PacoRG,或者可能要求您先接受cookie并将其发送给登录。
LiveHTTPHeaders还允许您修改标题和“重放” - 这使您可以修改发送到服务器的内容(任何标题,cookie,参数等),以帮助确定服务器登录时实际需要的内容。 p>
此外,我认为默认情况下LWP会自动跟随重定向,因此页面实际上可能会重定向,而您却没有看到它(我相信“simple_request”功能不会跟随重定向。)
在LWP回复中,您可以向后浏览任何重定向:
my $prev_res = $res->previous();
while ( $prev_res ) {
print $prev_res->status_line . "\n";
$prev_res = $prev_res->previous();
}
希望这有帮助!
答案 3 :(得分:-1)
您没有提交点击的提交按钮的名称;我怀疑另一端的代码正在检查请求中是否存在该变量,以查看表单是否已提交。
正如PacoRG指出的那样,提交按钮是一个图像;因此,通过在浏览器中单击该按钮进行提交将提交名为“login.x”和“login.y”的字段以及“登录”。
避免此类问题的一个好方法是使用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
。)