downloading csv files in delphi

2019-08-14 03:44发布

问题:

Using Indy Clients (IdHTTP) I can download csv files, if I know the actual web address of the file by using the following code, which works perfectly (original code):

procedure TForm1.Button1Click(Sender: TObject);  
  var  
  Url, LocalFile: String;  
  Strm: TFileStream;  
begin  
    Url := 'http://www.cvrda.org/boats/cvrda_handicap/cvrda_ratings_2009.csv';  
    LocalFile := 'C:\cvrda_ratings_2009.csv';  
    Strm := TFileStream.Create(LocalFile, fmCreate);  

    try  
      try  
        IdHTTP1.Get(Url, Strm);  
      finally  
        Strm.Free;  
      end;  
   except  
     DeleteFile(LocalFile);  
     raise;  
   end;  
end; 

http://www.cvrda.org/boats/cvrda_handicap/cvrda_handicap.htm is the web site and if I look at page source I get the href:"cvrda_ratings_2009.csv". Nice and easy.

But looking at this non-Delphi example from Stackoverflow, example here, the website is here , if I press the export button, I can download the csv file manually, but to programaticaly download the file, how do I get the whole url of the actual csv file? I can't find it anywhere.

So I guess my question is: Is there a way to get the whole url of any csv file that is being downloaded manually in TWebBrowser?

update

What I'm hoping to do is download a csv file programatically. But I don't know what the url of the csv file is. If I click the download button, in TWebBrowser, to download the csv file, a popup appears. I then have to manually press 'save' in the popup. I hoping to do this programatically. If I know the url, I can use Indy, but because I don't know the url of the csv file, I have to use TWebBrowser.

update(12Nov2012) Example 2 (This example needs a Tbutton and a TWebBrowser on a Form)

procedure TForm1.Button1Click(Sender: TObject);
var
  ovLinks: OleVariant;
  x:integer;
begin
  WebBrowser1.navigate('http://financials.morningstar.com/income-statement/is.html?t=AAPL&ops=clear');
  //wait for page to load
  ovLinks := WebBrowser1.OleObject.Document.all.tags('A');
  if ovLinks.Length > 0 then
  begin
    for x := 0 to ovLinks.Length-1 do
    begin
    if Pos('javascript:SRT_stocFund.Export()', ovLinks.Item(x).href) > 0 then
      begin
        ovLinks.Item(x).click;
        Break;
      end;
    end;
  end;
end;

Sam M's answer helped me understand a lot, and it works for many web pages, but not all. I have no idea how to make it work for the above Example 2. In the above example I can download the csv file manually, after programatically clicking the 'Export' button. But to download the csv file programatically in this example, I still need the url of the csv file. Any ideas on how to get the url of the csv file in this case.

回答1:

After the web browser has gotten the HTML document, you need to loop through the link tags. Based on the current page formatting, you would need to compare the innerText on each link to see which one you want. Once you find the desired link tag, get the href property. This will not work if the web page is modified in such a way that the innerText of the link you are looking for is changed by the people who run the web site.

procedure Parse;
var URL : string;
    i: integer;
    Document: variant;
begin
  Document := WebBrowser.Document AS IHTMLDocument3;
  for i := 0 to Document.Links.Length - 1 do begin
    if Document.Links.Item(i).innerText = 'here' then begin
      URL := Document.Links.Item(i).href;
      Break;
    end;
  end;
end;

If in the future the web page starts using tag ids or tag names, it's even easier. Use the getElementById function and then there's no need to loop through all the elements.