在 Delphi 5 中使用 Indy 下载 CSV
我知道有很多 Indy 线程,但我找不到符合我情况的线程。
我已获得一个包含用户名和密码表单的 URL。然后,该操作将指向 URL/reports.php,其中有多个超链接。
这些链接中的每一个都将定向到带有 URL 变量的页面,例如 reports.php?report=variablename,下载将立即开始。
到目前为止我的想法:
procedure TForm1.PostData(Sender: TObject);
var
paramList:TStringList;
url,text:string;
// IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocket1: TIdSSLIOHandlerSocket;
idLogFile1 : TidLogFile;
begin
idLogFile1 := TidLogFile.Create(nil);
with idLogFile1 do
begin
idLogFile1.Filename := 'C:\HTTPSlogfile.txt';
idLogFile1.active := True;
end;
IdHTTP1 := TIdHTTP.Create(nil);
IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocket.Create(nil);
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv23;
IdHTTP1.IOHandler := IdSSLIOHandlerSocket1;
IdHTTP1.HandleRedirects := true;
IdHTTP1.ReadTimeout := 5000;
IdHTTP1.Intercept := idLogFile1;
paramList:=TStringList.create;
paramList.Clear;
paramList.Add('loguser=testuser');
paramList.Add('logpass=duke7aunt');
paramList.Add('logclub=8005');
url := 'https://www.dfcdata.co.uk/integration/reports.php?report=live';
try
IdHTTP1.Post(url,paramList);
except
on E:Exception do
begin
showMessage('failed to post to: '+url);
ShowMessage('Exception message = '+E.Message);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
reportType : String;
begin
PostData(Self);
reportType := 'live';
GetUrlToFile('',reportType+'.csv');
end;
procedure TForm1.GetUrlToFile(AURL, AFile : String);
var
Output : TMemoryStream;
success : Boolean;
begin
success := True;
Output := TMemoryStream.Create;
try
try
IdHTTP1.Get(AURL, Output);
IdHTTP1.Disconnect;
except
on E : Exception do
begin
ShowMessage('Get failed to GET from '+IdHTTP1.GetNamePath +'. Exception message = '+E.Message);
success := False;
end;
end;
if success = True then
begin
showMessage('Filed saved');
Output.SaveToFile(AFile);
end;
finally
Output.Free;
end;
end;
每次尝试时我都会收到“IOHandler 无效”错误。显然我没有正确发布到初始页面,但有人可以告诉我我缺少什么吗?另外,我可以在登录后直接点击下载 URL 还是必须使用 cookie?
谢谢
I know there's alot of Indy threads but I can't get one to match my case.
I have been given a URL with a username and password form. this then actions to a URL/reports.php on which there are multiple hyperlinks.
Each of these links will direct to a page with URL variables e.g. reports.php?report=variablename where a download will immediately start.
My thinking so far:
procedure TForm1.PostData(Sender: TObject);
var
paramList:TStringList;
url,text:string;
// IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocket1: TIdSSLIOHandlerSocket;
idLogFile1 : TidLogFile;
begin
idLogFile1 := TidLogFile.Create(nil);
with idLogFile1 do
begin
idLogFile1.Filename := 'C:\HTTPSlogfile.txt';
idLogFile1.active := True;
end;
IdHTTP1 := TIdHTTP.Create(nil);
IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocket.Create(nil);
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv23;
IdHTTP1.IOHandler := IdSSLIOHandlerSocket1;
IdHTTP1.HandleRedirects := true;
IdHTTP1.ReadTimeout := 5000;
IdHTTP1.Intercept := idLogFile1;
paramList:=TStringList.create;
paramList.Clear;
paramList.Add('loguser=testuser');
paramList.Add('logpass=duke7aunt');
paramList.Add('logclub=8005');
url := 'https://www.dfcdata.co.uk/integration/reports.php?report=live';
try
IdHTTP1.Post(url,paramList);
except
on E:Exception do
begin
showMessage('failed to post to: '+url);
ShowMessage('Exception message = '+E.Message);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
reportType : String;
begin
PostData(Self);
reportType := 'live';
GetUrlToFile('',reportType+'.csv');
end;
procedure TForm1.GetUrlToFile(AURL, AFile : String);
var
Output : TMemoryStream;
success : Boolean;
begin
success := True;
Output := TMemoryStream.Create;
try
try
IdHTTP1.Get(AURL, Output);
IdHTTP1.Disconnect;
except
on E : Exception do
begin
ShowMessage('Get failed to GET from '+IdHTTP1.GetNamePath +'. Exception message = '+E.Message);
success := False;
end;
end;
if success = True then
begin
showMessage('Filed saved');
Output.SaveToFile(AFile);
end;
finally
Output.Free;
end;
end;
On each try I get "IOHandler is not valid" error. Obviously I'm not posting correctly to the initial page but can anyone advise me on what I'm missing? Also can I simply then hit the download URL after login or will I have to use cookies?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的代码中有几个错误:
1)
PostData()
正在请求 HTTPS URL,但它没有将启用 SSL 的 IOHandler 分配给TIdHTTP.IOHandler
属性。你需要这样做。2)
Button1Click()
将 URL 传递给GetUrlToFile()
,但未指定任何协议,因此TIdHTTP
最终会将该 URL 视为相对于其现有 URL,因此尝试从https://www.testurl.com/test/testurl.com/test/reports.php
下载,而不是https://testurl.com/test/reports.php
。如果您想请求相对 URL,请不要包含主机名(在本例中甚至不要包含路径,因为您将多个请求发送到同一路径,只是不同的文档)。3)您正在泄漏 TIdHTTP 对象。
There are several bugs in your code:
1)
PostData()
is requesting an HTTPS URL, but it is not assigning an SSL-enabled IOHandler to theTIdHTTP.IOHandler
property. You need to do so.2)
Button1Click()
is passing a URL toGetUrlToFile()
that does not specify any protocol, soTIdHTTP
will end up treating that URL as relative to its existing URL, and thus try to download fromhttps://www.testurl.com/test/testurl.com/test/reports.php
instead ofhttps://testurl.com/test/reports.php
. If you want to request a relative URL, don't include the hostname (or even the path in this case, since you are sending multiple requests to the same path, just different documents).3) you are leaking the TIdHTTP object.
问题 1) 现已在另一篇文章中得到解决:
Delphi 5 Indy/ics SSL 解决方法?
但是,我非常感谢有关以下问题的帮助休息一下,如下。
我是否需要使用相同的 IdHTTP 对象和附加 URL 变量进行 GET 调用?或者我应该创建一个新的 IdHTTP 对象?
我是否需要使用 cookie 记录会话,或者所有这些都可以通过同一个调用来完成吗?
上面的 GET 调用实际上是我将 csv 保存到文件所需要的吗?我也可以选择直接处理它,因为无论如何数据都需要导入。
目前代码收到错误:EIdHTTPProtocolException
Issue 1) has now been resolved in another post:
Delphi 5 Indy/ics SSL workaround?
However I would greatly appreciate help on the rest, as follows.
Would I need to make a GET call with the same IdHTTP object and additional URL variable? or should I create a new IdHTTP object?
Would I need to record the session using cookies or can all of this be done with the same call?
Is the GET call above actually what I need to save a csv to file? I may also choose to handle it directly as the data will need importing anyway.
Currently the code gets the error: EIdHTTPProtocolException