Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 768
  • Last Modified:

Get html source from a frame within an Internet Explorer page

Hi, I need a procedure that will get the source html from within a frame on a web page in an already open instance of Internet Explorer, the problem is that the page contains frames. I don't need anything complicated, the frame will always be the same one. The source html then needs to be dumped into a TMemo. Thanks.
0
iana1uk
Asked:
iana1uk
  • 3
  • 3
1 Solution
 
Eddie ShipmanAll-around developerCommented:
Normally, you would get the frame src attribute using the DOM and then get the source using idHTTP like this:

procedure TForm1.Button1Click(Sender: TObject);
var
  ShellWin : TShellWindows;
  i, j : integer;
  IE : IWebBrowser2;
  HTMLDocument: IHTMLDocument2;
  frame: olevariant;
  x: OleVariant;
  s: String;
  frames: IHTMLFramesCollection2;
begin
  ShellWin := TShellWindows.Create(nil);
  try
    for i := 0 to ShellWin.Count-1 do
      begin
        try
          ShellWin.Item(i).QueryInterface(IID_IWebBrowser2, IE);
          try
            HTMLDocument := IE.Document as IHTMLDocument2;
            frames := HTMLDocument.frames;
            for j := 0 to frames.length-1 do
            begin
              x := j;
              frame := frames.item(x);
              if UpperCase(frame.name) = 'MAINFRAME' then
              begin
                s := frame.src;
                Memo1.Text := idhttp1.get(s);
              end;
            end;
          finally
             HTMLDocument := nil;
          end;
        except
        end;
      end;
  finally
    ShellWin.Free;
  end;
end;

But, new security restrictions in IE no longer allow that. There is no way to get it without parsing it
using string functions. Now, keep in mind that some sites may have absolute URLS and some may use relative
URLS and that would make a big difference in your parsing.
uses ..., mshtml, SHDocVW;

function RatChar(S:String; C: Char):Integer;
var
  i : Integer;
begin
  i := Length(S);
  while (S[i] <> C) and (i > 0) do
    Dec(i);
  Result := i;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ShellWin : TShellWindows;
  i : integer;
  IE : IWebBrowser2;
  HTMLDocument: IHTMLDocument2;
  frame: String;
  src: String;
  x: Integer;
  sl: TStringList;
  srcPos: Integer;
  framepos: Integer;
  baseurl: String;
begin
  ShellWin := TShellWindows.Create(nil);
  try
    for i := 0 to ShellWin.Count-1 do
      begin
        try
          ShellWin.Item(i).QueryInterface(IID_IWebBrowser2, IE);
          try
            HTMLDocument := IE.Document as IHTMLDocument2;
            baseurl := Copy(IE.LocationURL, 1, RatChar(IE.LocationURL, '/'));
            sl := TStringList.Create;
            try
              sl.text := HTMLDocument.body.outerHTML;
              frame := 'mainFrame';
              for x := 0 to sl.Count-1 do
              begin
                // locate the frame that you want:
                if Pos(UpperCase('<frame name='+frame), UpperCase(sl[x])) > 0 then
                begin
                  framepos := Pos(UpperCase('<frame name='+frame), UpperCase(sl[x]));
                  src := Copy(sl[x], framePos, Length(sl[x]));
                  srcpos := Pos(UpperCase('src='), UpperCase(src)) + 5;
                  src := Copy(src, srcPos, Length(sl[x]));
                  src := Copy(src, 1, Pos('"', src)-1);
                  Memo1.Lines.Text := idHTTP1.Get(baseurl+ src);
                end;
              end;
            finally
               sl.Free;
            end;
          finally
             HTMLDocument := nil;
          end;
        except
        end;
      end;
  finally
    ShellWin.Free;
  end;
end;
0
 
iana1ukAuthor Commented:
Hi Eddie, thanks for the quick reply, I have implemented the code above, added an idHTTP component (as one is referenced in the code) and the frame name is mainFrame, so no change needed there. Code executes without error, but when the button is pressed, nothing happens, Memo1 remains unchanged.

The frames are called using a relative URL.

Another point is that the page being retrieved has to be the one that is currently displayed as it is returning information that is different every time it is called.
0
 
Eddie ShipmanAll-around developerCommented:
Got a URL for me to test on? I tested on http://reportman.sourceforge.net/doc/index.html, only framed site I knew of OTTOMH.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
iana1ukAuthor Commented:
Hi Eddie, problem solved, it might be an untidy hatchet job, but it seems to do what I need. I've used some of your code above, the points are yours, thanks for your help! Ian.

procedure TForm1.Button5Click(Sender: TObject);
var
  ShellWin : TShellWindows;
  i,x : integer;
  IE : IWebBrowser2;
  Document: IHTMLDocument2;
  Frame: IDispatch;
  FrameNum: OleVariant;
  FrameDoc: IHTMLDocument2;
begin
  ShellWin := TShellWindows.Create(nil);
  for i := 0 to ShellWin.Count-1 do
  begin
    ShellWin.Item(i).QueryInterface(IID_IWebBrowser2, IE);
    Document := IE.Document as IHTMLDocument2;
  end;
  try
    x := Document.Frames.Length;
    if x <> 0 then
      for x := 0 to x - 1 do
      try
        FrameNum := x;
        Frame := Document.Frames.Item(FrameNum);
        FrameDoc := (Frame as IHTMLWindow2).Document as IHTMLDocument2;
        Memo1.Text := FrameDoc.Get_body.Get_outerHTML;
      except
      end;
   except
   end;
  Document := nil;
  ShellWin.Free;
end;
0
 
Eddie ShipmanAll-around developerCommented:
Oh, DAMN, I forgot about the IHTMLWindow2 object. I'm surprised that IE Security let you do it, though.
0
 
iana1ukAuthor Commented:
I knew of it but didn't quite know how it worked. I borrowed a couple of lines of code from the IESnifferAutoFill components. I'm just happy it's now doing what I want!
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now