Autor Beitrag
CABALxx
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 174


D7 Ent
BeitragVerfasst: Mo 19.12.05 23:45 
Hallo Leute


Ich hab ein kleines Problem: Ein Code den ich sonst immer verwendet hab funktioniert bei einer neuen Anwendung irgendwie nicht mehr wie er sollte aber ich kann da keinen Grund für sehen:

Ich hab vorher immer einen Chat ausgelesen, und zwar den Quelltext des Framegerüsts und der einzelnen Frames mit folgendem Code:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
function TForm1.GetFrame(FrameNo: Integer): IWebbrowser2;
var
  OleContainer: IOleContainer;
  enum: IEnumUnknown;
  unk: IUnknown;
  Fetched: PLongint;
begin
  while Webbrowser1.ReadyState <> READYSTATE_COMPLETE do
    Application.ProcessMessages;
  if Assigned(Webbrowser1.document) then
  begin
    Fetched := nil;
    OleContainer := Webbrowser1.Document as IOleContainer;
    OleContainer.EnumObjects(OLECONTF_EMBEDDINGS, Enum);
    Enum.Skip(FrameNo);
    Enum.Next(1, Unk, Fetched);
    Result := Unk as IWebbrowser2;
  end  
  else
    Result := nil
end;


procedure TForm1.Timer1Timer(Sender: TObject);
var
  s : TStringList;
  IpStream: IPersistStreamInit;
  AStream: TMemoryStream;
  iw: IWebbrowser2;
  i: Integer;
  sl: TStringList;
begin
  for i := 0 to Webbrowser1.OleObject.Document.frames.Length - 1 do
  begin
    iw := GetFrame(i);
    AStream := TMemoryStream.Create;
    try
      IpStream := iw.document as IPersistStreamInit;
      if Succeeded(IpStream.save(TStreamadapter.Create(AStream), True)) then
      begin
        AStream.Seek(00);
        sl := TStringList.Create;
        sl.LoadFromStream(AStream);
        sl.SaveToFile('c:\frame' + IntToStr(i) + '.txt');
       // memo1.Lines.LoadFromStream(AStream);
        sl.Free;
      end
    except
    end;
    AStream.Free;
  end;
  begin
s:= TStringList.Create;
s.LoadFromFile('C:\frame1.txt');

Memo1.lines.AddStrings(s);
end;
end;



Das hat früher auch wunderbar funktioniert. Hat dann Dateien erstellt Frame1.txt usw und da stand dann der Quelltext des jeweiligen Frames drin.

Aber nun hab ich den auf einen neuen Chat anwenden wollen und da funktioniert er nicht mehr?!
Er erstellt nicht mal die Dateien,

Ich poste auch mal den Quelltext vom Framegerüst des Chats, vll liegts ja daran?


ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
<HTML>
<HEAD>
<TITLE> RapidChat V3.3.1 </TITLE>

<script language="javascript">
<!--
var uid_keycode = "68382535889089";
-->
</script>
<script type="text/javascript" src="http://images.rapidforum.com/chatimages/lb_communicator/functions_ger.js"></script>

</HEAD>

<FRAMESET FRAMESPACING="0" ROWS="127,*,75" border="0">
    <FRAME NAME="top68382535889089" SRC="http://chat.rapidchat.de/chat?keycode=68382535889089§ion=top" MARGINHEIGHT="0" MARGINWIDTH="0" SCROLLING="NO" NORESIZE frameborder=no>
    <FRAMESET FRAMESPACING="0" COLS="*,193" border="0">
      <FRAME NAME="main68382535889089" SRC="http://chat.rapidchat.de/chat?keycode=68382535889089§ion=main" MARGINHEIGHT="10" MARGINWIDTH="10" SCROLLING="YES" NORESIZE frameborder=no>
      <FRAMESET ROWS="*,180" FRAMESPACING="0" border="0">
        <FRAME NAME="nicklist68382535889089" SRC="http://chat.rapidchat.de/chat?keycode=68382535889089§ion=nicklist" MARGINHEIGHT="0" MARGINWIDTH="0" SCROLLING="YES" NORESIZE frameborder=no>
        <FRAME NAME="commands68382535889089" SRC="http://chat.rapidchat.de/chat?keycode=68382535889089§ion=commands" MARGINHEIGHT="0" MARGINWIDTH="0" SCROLLING="AUTO" NORESIZE frameborder=no>
      </FRAMESET>
    </FRAMESET>
    <FRAMESET ROWS="11,22,*" FRAMESPACING="0" border="0">
      <FRAME NAME="command_top68382535889089" SRC="http://chat.rapidchat.de/chat?keycode=68382535889089§ion=command_top" MARGINHEIGHT="0" MARGINWIDTH="0" SCROLLING="NO" NORESIZE frameborder=no>
      <FRAME NAME="command68382535889089" SRC="http://chat.rapidchat.de/chat?keycode=68382535889089§ion=console" MARGINHEIGHT="0" MARGINWIDTH="0" SCROLLING="NO" NORESIZE frameborder=no>
      <FRAME NAME="command_bottom68382535889089" SRC="http://chat.rapidchat.de/chat?keycode=68382535889089§ion=command_bottom" MARGINHEIGHT="0" MARGINWIDTH="0" SCROLLING="NO" NORESIZE frameborder=no>
    </FRAMESET>
</FRAMESET>


<NOFRAMES>
Der Chat benutzt Frames für die Darstellung, sollten Sie diesen Text lesen bedeutet dies, das ihr Browser die Anzeige von Frames nicht unterstützt oder ggf. eine hierfür benötigte Option in den Browsereinstellungen deaktiviert ist.
</NOFRAMES>


</HTML>




Ich verstehs irgendwie nicht.
CABALxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 174


D7 Ent
BeitragVerfasst: Di 20.12.05 01:05 
soo
ich bin selbst ein bisschen weiter gekommen

mit



ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Button2Click(Sender: TObject);
begin

Memo1.Text:= WebBrowser1.OleObject.Document.documentElement.innerHTML;
end;



hab ich immerhin schonmal das beschriebene Framegerüst gekriegt, das bringt mich schon sehr weiter.

Aber ich bräuchte noch die quelltexte der einzelnen Frames an sich.
kann ich das auch mit dem innerHTML und dem Webbrowser machen? das kann man doch irgenwie auch auf ein Frame beziehen oder?

Danke schonmal
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Di 20.12.05 12:27 
Hallo,
user profile iconCABALxx hat folgendes geschrieben:
...Aber ich bräuchte noch die quelltexte der einzelnen Frames an sich.
kann ich das auch mit dem innerHTML und dem Webbrowser machen? das kann man doch irgenwie auch auf ein Frame beziehen oder?

ja, das geht :wink:
In dem Thread zu einem ähnliche Thema in der DP
TWebBrowser : Alle Input Felder, Bilder etc. auflisten
hatte ich mal so meine Gedanken niedergeschrieben, die zu dem Ergebnis führten,
das da eine rekursive Lösung angebracht ist.

Inzwischen bin ich schon einen großen Schritt weitergekommen.
Es fehlt noch eine Fehlerbehandlung.

Hab meine Prozedur zum Auslesen aller Images mal auf innerHtML umgestellt.
Die Prozedur liest aus allen Frames incl. eventueller IFrame den HTML-Code aus
und schreibt ihn nacheinander in ein Memo.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure GetAllInnerHtml(aDoc: OleVariant;aMemo: TMemo);
var z,
    Count    : Integer;
    aDocLokal : OleVariant;
begin
  aDocLokal := aDoc;
  aMemo.Lines.Add(aDocLokal.documentElement.innerHTML);
  aMemo.Lines.Add('************* Neues documentElement *****');
  count := aDocLokal.frames.length;
  for z := 0 to Count-1 do
    begin
    aDoc := aDocLokal.frames.item(z).document;
    GetAllInnerHtml(aDoc,aMemo);//recursive
    end;
end;

procedure TForm1.Button10Click(Sender: TObject);
begin
  GetAllInnerHtml(WebBrowser1.OleObject.Document,Memo1);
end;

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
CABALxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 174


D7 Ent
BeitragVerfasst: Di 20.12.05 12:27 
Ich wollte das jetzt mal mit einem alternativ- Code von www.swissdelphicente...showcode.php?id=2054

probieren: aber irgendwie hakts da:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
 private
  function GetBrowserForFrame(Doc: IHTMLDocument2; nFrame: Integer): IWebBrowser2;
  function GetFrameSource(WebDoc: iHTMLDocument2): string;
  function WB_SaveFrameToFile(HTMLDocument: IHTMLDocument2; const FileName: TFileName): Boolean;
  function SaveWBFrames(WebBrowser1: TWebBrowser): string;
    { Private-Deklarationen }

  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetBrowserForFrame(Doc: IHTMLDocument2; nFrame: Integer): IWebBrowser2;
  //Thanks to Rik Barker
  //returns an interface to the frame's browser
var
  pContainer: IOLEContainer;
  enumerator: ActiveX.IEnumUnknown;
  nFetched: PLongInt;
  unkFrame: IUnknown;
  hr: HRESULT;
begin
  Result := nil;
  nFetched := nil;
  // Cast the page as an OLE container
  pContainer := Doc as IOleContainer;
  // Get an enumerator for the frames on the page
  hr := pContainer.EnumObjects(OLECONTF_EMBEDDINGS or OLECONTF_OTHERS, enumerator);
  if hr <> S_OK then
  begin
    pContainer._Release;
    Exit;
  end;
  // Now skip to the frame we're interested in
  enumerator.Skip(nFrame);
  // and get the frame as IUnknown
  enumerator.Next(1,unkFrame, nFetched);
  // Now QI the frame for a WebBrowser Interface - I'm not  entirely
  // sure this is necessary, but COM never ceases to surprise me
  unkframe.QueryInterface(IID_IWebBrowser2, Result);
end;


function GetFrameSource(WebDoc: iHTMLDocument2): string;
  //returns frame HTML and scripts as a text string
var
  re: integer;
  HTMLel: iHTMLElement;
  HTMLcol: iHTMLElementCollection;
  HTMLlen: Integer;
  ScriptEL: IHTMLScriptElement;
begin
  Result := '';
  if Assigned(WebDoc) then
  begin
    HTMLcol := WebDoc.Get_all;
    HTMLlen := HTMLcol.Length;
    for re := 0 to HTMLlen - 1 do
    begin
      HTMLel := HTMLcol.Item(re, 0as iHTMLElement;
      if HTMLEl.tagName = 'HTML' then
        Result := Result + HTMLEl.outerHTML;
    end;
  end;
end;

function WB_SaveFrameToFile(HTMLDocument: IHTMLDocument2;
  const FileName: TFileName): Boolean;
// Save IHTMLDocument2 to a file
var
  PersistFile: IPersistFile;
begin
  PersistFile := HTMLDocument as IPersistFile;
  PersistFile.Save(StringToOleStr(FileName), System.True);
end;

function SaveWBFrames(WebBrowser1: TWebBrowser): string;
// return the source for all frames in the browser
var
  Webdoc, HTMLDoc: ihtmldocument2;
  framesCol: iHTMLFramesCollection2;
  FramesLen: integer;
  pickFrame: olevariant;
  p: integer;
begin
  try
    WebDoc := WebBrowser1.Document as IHTMLDocument2;
    Result := GetFrameSource(WebDoc);

    // §§§ Hier kann Result in eine Datei gespeichert werden §§§§  oder  mit
    // WB_SaveFrameToFile(WebDoc,'c:\MainPage.html');

    //Handle multiple or single frames
    FramesCol := WebDoc.Get_frames;
    FramesLen := FramesCol.Get_length;
    if FramesLen > 0 then
      for p := 0 to FramesLen - 1 do
      begin
        pickframe := p;
        HTMLDoc   := WebBrowser1.Document as iHTMLDocument2;

        WebDoc := GetBrowserForFrame(HTMLDoc, pickframe).document as iHTMLDocument2;
        if WebDoc <> nil then
        begin
          Result := GetFrameSource(WebDoc);
          WB_SaveFrameToFile(WebDoc, 'c:\Frame' + IntToStr(p) + '.html');
          // ShowMessage(HTMLDoc.Get_parentWindow.Get_name);
          // ShowMessage(HTMLDoc.Get_parentWindow.Parent.Get_document.nameProp);

        end;
      end;
  except
    Result := 'No Source Available';
  end;
end;



Ich krieg bei den Deklarationen oben bei den Funktionen diverse Debuggermeldungen .
Vielleicht ja jmd. ne Idee.




////EDIT


Ahoi

Danke Lannes, ich werd den Code gleich mal ausprobieren. :D
CABALxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 174


D7 Ent
BeitragVerfasst: Di 20.12.05 13:01 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.GetAllInnerHtml(aDoc: OleVariant;aMemo: TMemo);
var z,
    Count    : Integer;
    aDocLokal : OleVariant;
begin
  aDocLokal := aDoc;
  aMemo.Lines.Add(aDocLokal.documentElement.innerHTML);
  aMemo.Lines.Add('************* Neues documentElement *****');
  count := aDocLokal.frames.length;
  for z := 0 to Count-1 do
    begin
    [b]aDoc := aDocLokal.frames.item(z).document;[/b]
    GetAllInnerHtml(aDoc,aMemo);//recursive
    end;
end;



An der Stelle:

ausblenden Quelltext
1:
aDoc := aDocLokal.frames.item(z).document;					



gibt er mir eine Fehlermeldung wenn ich das Programm benutze. Lasse ich das weg, funktionierts, gibt aber nur das Framegerüst aus.
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Di 20.12.05 13:11 
Hallo,

und welche Fehlermeldung?

Wenn ich die Seite chat.rapidchat.de aufrufe,
dann den Button [Login] betätige,
warte bis vollständig geladen ist,
bekomme ich alle Frame-Inhalte.

user profile iconCABALxx hat folgendes geschrieben:
Lasse ich das weg, funktionierts, gibt aber nur das Framegerüst aus.

Das ist klar,
weil dann das rekursiv ermittelte Frame nicht gelesen wird. :wink:

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
CABALxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 174


D7 Ent
BeitragVerfasst: Di 20.12.05 13:33 
Ahoi

Also

Dein Code hier funktioniert wunderbar! Vielen Dank dafür ist echt ne klasse Lösung für ein wirklich großes Problem ! Bin beeindruckt :D :D :D :D :D :D


Mein Problem lag irgendwie an der Homepage , auf der ich den Chat hatte. Wenn ich direkt von rapidchat.de rein gehe, geht alles prima.


Danke dir vielmals ist echt ne optimallösung

:D :D :D