gpt4 book ai didi

delphi - 在 Delphi 中使用 idHTTP 发布表单数据

转载 作者:行者123 更新时间:2023-12-03 15:56:14 26 4
gpt4 key购买 nike

我使用 Delphi 和 IdHTTP lib 从此 URL ( http://apply.dataprocessors.com.au ) 获取表单,处理难题并发布正确答案。但是,显然我没有正确处理 POST 方法,一旦检索到的响应是:“提交问题。请重试。”

下面是Delphi源代码:

procedure TForm1.Button1Click(Sender: TObject);
var
sGET, sPOST, sGET_count: String;
countCircles: integer;
parameters: TStringList;
begin
parameters := TStringList.Create;
sGET := http.Get('http://apply.dataprocessors.com.au');
sGET_count := StringReplace(sGET, '$', ' ', [rfReplaceAll, rfIgnoreCase]);
sGET_count := StringReplace(sGET_count, 'unfilled', '$', [rfReplaceAll, rfIgnoreCase]);
countCircles := 120 - sGET_count.CountChar('$');

parameters.Add('title=submit');
parameters.Add('value=' + countCircles.ToString());
parameters.Add('submit=Submit');
http.Request.ContentType := 'application/x-www-form-urlencoded';
sPOST := http.Post('http://apply.dataprocessors.com.au/?', parameters);
txtPost.Lines.Add(sPOST);
end;

Form retrieved

HTML 代码:

<html>
<head>
</head>
<body>
<form action="" method="POST">
<input type="hidden" name="title" value="submit">
<p>How many filled circles do you see:? <br><img src="unfilled_O.gif" height="12" width="12"><br></p>
<p>Answer: <input type="text" name="value" value="" size="10"></p>
<p><input type="Submit" value="Submit">
</form></body>
</html>

从 POST 方法检索响应:

<html>
<head>
</head>
<body>
<p>Problem with submission. Please try again.</p></body>
</html>

最佳答案

我认为您的 TIdHTTP 代码没有问题(尽管 Post() 的 URL 末尾有 /? > 不是必需的)。 您的 TIdHTTP 代码中缺少步骤。有关详细信息,请参阅下文。

我还发现您的 StringReplace() 代码存在问题:

sGET := http.Get('http://apply.dataprocessors.com.au');
sGET_count := StringReplace(sGET, '$', ' ', [rfReplaceAll, rfIgnoreCase]);
sGET_count := StringReplace(sGET, 'unfilled', '$', [rfReplaceAll, rfIgnoreCase]);

注意第二个StringReplace() 的第一个参数。在第二次调用中,您将搜索由 TIdHTTP.Get() 返回的原始 HTML。您没有搜索第一个 StringReplace() 的结果。然后,当您重新分配 sGET_count 时,您将完全丢弃第一个 StringReplace() 的结果,从而有效地使第一次调用成为无操作。您可能打算这样做:

sGET := http.Get('http://apply.dataprocessors.com.au');
sGET_count := StringReplace(sGET, '$', ' ', [rfReplaceAll, rfIgnoreCase]);
sGET_count := StringReplace({sGET}sGET_count, 'unfilled', '$', [rfReplaceAll, rfIgnoreCase]);

更新:当我在网络浏览器中访问该 URL 时,我发现您的代码没有考虑到一些事情。第一,网络表单包含一个 jobref 字段,您未将其包含在 POST 提交中。但更重要的是,当真实的网络浏览器检索该网页时,相关网页会调用 JavaScript 函数,但当您当前的 TIdHTTP 设置检索该网页时则不会。该 Javascript 位于 http://apply.dataprocessors.com.au/funcs1.js 并包含一个用于动态向网络浏览器添加 cookie 的命令:

function init() {
document.cookie = 'pc3o=d2r22; path=';
}

该命令由 HTML 调用:

<html>
<head>
...
<script type="text/javascript" src="funcs1.js"></script>
</head>
<body onLoad="init()">
...
</html>

当网络浏览器提交网络表单时,除了检索 HTML 时 HTTP header 中存在的普通 PHP cookie 之外,该额外的 cookie 还会发送回网络服务器。您需要将 TIdHTTP.AllowCookies 属性设置为 True(默认情况下为 False),以便 TIdHTTP.Post() 可以发回 cookie,但是 Post( ) 默认情况下只会发送 PHP cookie,而不是 Javascript cookie,原因很明显(TIdHTTP 不调用客户端脚本)。

如果您更改 TIdHTTP.Request.UserAgent 属性来模拟真实的网络浏览器,而不是使用 Indy 的默认 UserAgent,则下载的 HTML 将包含该 JavaScript 引用。这是可选的,因为您可以手动将 Javascript cookie(幸运的是它是静态的,因此您不需要实际解析 Javascript,但如果您愿意的话可以)添加到 TIdHTTP.CookieManager无论 UserAgent 是什么,Post() 仍然会发送它,并且服务器似乎并不关心 HTML 是否包含 JavaScript 引用。

话虽如此,以下代码对我有用(我让服务器向 POST 发送成功响应):

procedure TForm1.Button1Click(Sender: TObject);
var
sGET, sPOST, sGET_count: String;
countCircles: integer;
parameters: TStringList;
begin
parameters := TStringList.Create;
try
http.AllowCookies := True;
// optional: http.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko';

sGET := http.Get('http://apply.dataprocessors.com.au');
http.CookieManager.AddServerCookie('pc3o=d2r22; path=', http.URL);

sGET_count := StringReplace(sGET, '$', '', [rfReplaceAll, rfIgnoreCase]);
sGET_count := StringReplace(sGET_count, '"filled_O.gif"', '$', [rfReplaceAll, rfIgnoreCase]);
countCircles := sGET_count.CountChar('$');

parameters.Add('title=submit');
parameters.Add('jobref=');
parameters.Add('value=' + countCircles.ToString());

http.Request.ContentType := 'application/x-www-form-urlencoded';
http.Request.Referer := 'http://apply.dataprocessors.com.au';

sPOST := http.Post('http://apply.dataprocessors.com.au', parameters);
ShowMessage(sPOST);
finally
parameters.Free;
end;
end;

关于delphi - 在 Delphi 中使用 idHTTP 发布表单数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33365278/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com