Помогите пожалуйста, проблема с компонентом Webbrowser
От: ratttx  
Дата: 30.05.06 18:41
Оценка:
Я могу найти URL адреса всех фреймов на сайте, и умею заполнять формы и нажимать кнопки. Это делается через:
ovElements:= Webbrowser.OleObject.Document.frames.item(2).Document.forms.item(0).elements;
Так я определил к какому фрейму я обращаюсь и могу заполнять все, что мне надо....
Я могу вынуть HTML код всего сайта и записать его в мемо...
Это делается так.....
procedure TForm1.Button2Click(Sender: TObject);
var
Document: IHtmlDocument2;
begin
Document := WB.Document as IHtmlDocument2;
if Document <> nil then richedit1.Text := (Document.all.Item(NULL, 0) as IHTMLElement).OuterHTML;
end;
----------------------------------------------------
Но есть проблема, что на сайте МНОГО ФРЕЙМОВ, и мне выдается ХТМЛ код не того, что мне нужно, а если я пробую обратиться к фрейму как описал выше, а после воспользоваться этой процедурой, то мне выкидывает ошибку примерно такую -"Я обьявил ОЛЕэлемент и пытаюсь вытащить код ЭТОГО ЭЛЕМЕНТА(Ему все равно, что этот элемент является фреймом...)" (ovElements:= Webbrowser.OleObject.Document.frames.item(2).Document — эта фишка не работает... (((((((((((
Так вот итог....
КАК ВЫТАЩИТЬ ХТМЛ КОД ИЗ ОПРЕДЕЛЕННОГО(например мне нужен фрейм 2) ФРЕЙМА НА САЙТЕ И ЗАПИСАТЬ ЕГО В МЕМО?

В интернете искал, там какой то бред
ВАРИАНТ "ЗАГРУЗИ ЭТОТ ФРЕЙМ, КАК ГЛАВНЫЙ(ОДИН НА ВСЕ ОКНО) НЕ ПОДХОДИТ, ВОЗНИКАЕТ ДРУГАЯ ОШИБКА, ТОЛЬКО УЖЕ С JAVA СКРИПТАМИ", ТУ ОШИБКУ ИСПРАВИТЬ Я ТОЖЕ НЕ ЗНАЮ КАК

Помогите плиз, пришлите мне код, как это делается(пример),буду очень благодарен
Re: Помогите пожалуйста, проблема с компонентом Webbrowser
От: Ihor Osovyak Украина  
Дата: 30.05.06 19:14
Оценка:
Здравствуйте, ratttx, Вы писали:

R>ovElements:= Webbrowser.OleObject.Document.frames.item(2).Document.forms.item(0).elements;


не совсем хороший подход, хотя бы потому что в силу определенных обстоятельств на соотв. уровне может быть несколько меньше фреймов, чем Вы ожидаете, как следствие — ексепшен.. Ну и плюс проблема, упомянутая Вами далее.


R>if Document <> nil then richedit1.Text := (Document.all.Item(NULL, 0) as IHTMLElement).OuterHTML;


не совсем хорошо также, так как в общеи случае не обязательно должег существоапть Document.all.Item(NULL, 0) и не обязательно он имеет интерфейс IHTMLElement...


Посмотрите мою древнюю статью на Королевстве делфи в Подземелье магов, писалась давно, но в общем то немного имеет актуальность, там немного другой подход.. Кажется, там также есть пример работы с фреймами (или это только планировал писать в продолжении, если это так — стучите еще раз, брошу пример сюда)...

http://www.delphikingdom.com/asp/viewitem.asp?catalogID=366



R>end;

R>Но есть проблема, что на сайте МНОГО ФРЕЙМОВ, и мне выдается ХТМЛ код не того, что мне нужно,

подозреваю, что Вы не учитываете того, что фреймы не обязательно все на одном уровне, а могут быть вложены друг в друга (тохоже как директории на диске, а Ваш код проходит только по коревой директории (аналогия верна в первом приближении, прошу не судить строго)

а если я пробую обратиться к фрейму как описал выше, а после воспользоваться этой процедурой, то мне выкидывает ошибку примерно такую -"Я обьявил ОЛЕэлемент и пытаюсь вытащить код ЭТОГО ЭЛЕМЕНТА(Ему все равно, что этот элемент является фреймом...)" (ovElements:= Webbrowser.OleObject.Document.frames.item(2).Document — эта фишка не работает... (((((((((((


ну об чем и речь, я уже об этом говорил..

удачи..
Re[2]: Помогите пожалуйста, проблема с компонентом Webbrowse
От: ratttx  
Дата: 30.05.06 21:32
Оценка:
Здравствуйте, Ihor Osovyak.

Большое спасибо за вашу статью, но прочитав ее я понял, на сколько я глупый.... )
Я сильно извиняюсь но не могли бы вы написать небольшой кодик на простой буттон(или ОНДОКУМЕНТкомплит), что бы он просто вынимал ХТМЛкод из всех фреймов и заносил их все в мемо... В статье, я так и не понял, как это делается, потыкался, потыкался и опять сполз на 0...
Еще раз извиняюсь за принесенные неудобства....
Re[3]: Помогите пожалуйста, проблема с компонентом Webbrowse
От: Ihor Osovyak Украина  
Дата: 30.05.06 21:56
Оценка:
Здравствуйте, ratttx, Вы писали:

R>Здравствуйте, Ihor Osovyak.


R>Большое спасибо за вашу статью, но прочитав ее я понял, на сколько я глупый.... )


а зря, статья расчитана на бегин0левел ...

R>Я сильно извиняюсь но не могли бы вы написать небольшой кодик на простой буттон(или ОНДОКУМЕНТкомплит), что бы он просто вынимал ХТМЛкод из всех фреймов и заносил их все в мемо... В статье, я так и не понял, как это делается, потыкался, потыкался и опять сполз на 0...

R>Еще раз извиняюсь за принесенные неудобства....


выдернуто из того, что под рукой....


unit fIEFrames;

interface
uses Mshtml;

type
  TOneStepSearchCondForHtmlDocWithFrames = function(iDoc: IHtmlDocument2; addPrm: integer): boolean;

function FinderFirstCondForHtmlDocWithFrames(iDoc: IHtmlDocument2;
  addPrm: integer;
  aDoer: TOneStepSearchCondForHtmlDocWithFrames): boolean;


implementation

uses sysutils;

function FinderFirstCondForHtmlDocWithFrames(iDoc: IHtmlDocument2;
  addPrm: integer;
  aDoer: TOneStepSearchCondForHtmlDocWithFrames): boolean;
{  The procedure aDoer  will be caused for each IHtmlDocument2, beginning
   from main and finishing any level of frames
   while aDoer will return false;
}
var
  frames: IHTMLFramesCollection2;
  i: integer;
  ov1: OleVariant;
  iDisp: IDispatch;
  IWindow2: IHTMLWindow2;
begin
  result := false;
  if not assigned(aDoer) then
    Exit;
  result := aDoer(iDoc, addPrm);
  if result then
    Exit;
  frames := iDoc.frames;
  if not assigned(frames) then
    exit;
  if frames.length = 0 then
    exit;

  for i := 1 to frames.length do
  begin
    ov1 := i - 1;
    try
      iDisp := frames.item(ov1);
      iDisp.QueryInterface(IHTMLWindow2, IWindow2);
      if assigned(IWindow2) then
      begin
        result := false;
        try
          if assigned(IWindow2.document) then
            result := FinderFirstCondForHtmlDocWithFrames(IWindow2.document, addPrm, aDoer);
        except
        end;
        if result then
          exit;
      end;
    except
      { ShowMessage('Find error !!!');}
    end;
  end;
end;

end.



и далее


unit e0_PrimParser;

interface

uses classes, Mshtml, SHDocVw;

....

function GetHtmlAllFrames(pDisp: IDispatch): string;
function GetHtmlAllFrames2(iDoc: IHtmlDocument2): string;

function GetTxtAllFrames2(iDoc: IHtmlDocument2): string;
function GetTxtAllFrames(pDisp: IDispatch): string;


implementation

uses
  variants,
  activeX,
  sysutils,
  fIEFrames;

type

.....
  pdataFor_getTextAllFrames = ^dataFor_getTextAllFrames;
  dataFor_getTextAllFrames = record
    sStr: string;
  end;


......

function fGetAllHTMOneFrame(iDoc: IHtmlDocument2; addPrm: integer): boolean;

var
  ov: OleVariant;
  iDisp: IDispatch;
  iColl: IHTMLElementCollection;
  iElement: IHTMLElement;
  i: integer;
  //subStr:string;
  tag: string;
begin
  result := false;
  if addPrm = 0 then
    Exit;

  if not assigned(iDoc) then
    Exit;
  tag := 'BODY';
  ov := tag;

  IDisp := iDoc.all.tags(ov);
  if not assigned(IDisp) then
    exit;
  IDisp.QueryInterface(IHTMLElementCollection, iColl);
  if not assigned(iColl) then
    exit;

  for i := 1 to iColl.Get_length do
  begin
    iDisp := iColl.item(pred(i), 0);
    if not assigned(iDisp) then
      continue;
    iDisp.QueryInterface(IHTMLElement, iElement);
    if not assigned(iElement) then
      continue;
    try
      with pdataFor_getTextAllFrames(addPrm)^ do
        sStr := sStr + iElement.outerHTML;
    except
    end;
  end;
end;

function fGetTxtOneFrame(iDoc: IHtmlDocument2; addPrm: integer): boolean;

var
  ov: OleVariant;
  iDisp: IDispatch;
  iColl: IHTMLElementCollection;
  iElement: IHTMLElement;
  i: integer;
  //subStr:string;
  tag: string;
begin
  result := false;
  if addPrm = 0 then
    Exit;

  if not assigned(iDoc) then
    Exit;
  tag := 'BODY';
  ov := tag;

  IDisp := iDoc.all.tags(ov);
  if not assigned(IDisp) then
    exit;
  IDisp.QueryInterface(IHTMLElementCollection, iColl);
  if not assigned(iColl) then
    exit;

  for i := 1 to iColl.Get_length do
  begin
    iDisp := iColl.item(pred(i), 0);
    if not assigned(iDisp) then
      continue;
    iDisp.QueryInterface(IHTMLElement, iElement);
    if not assigned(iElement) then
      continue;
    try
      with pdataFor_getTextAllFrames(addPrm)^ do
        sStr := sStr + iElement.outerText;
    except
    end;
  end;
end;

function GetHtmlAllFrames2(iDoc: IHtmlDocument2): string;
var
  data: dataFor_getTextAllFrames;
begin
  result := '';

  if not assigned(iDoc) then
    Exit;

  fillChar(data, sizeof(data), 0);
  data.sStr := '';

  FinderFirstCondForHtmlDocWithFrames(iDoc, integer(@Data), fGetAllHTMOneFrame);
  result := data.sStr;

  data.sStr := '';

end;

function GetTxtAllFrames2(iDoc: IHtmlDocument2): string;
var
  data: dataFor_getTextAllFrames;
begin
  result := '';

  if not assigned(iDoc) then
    Exit;

  fillChar(data, sizeof(data), 0);
  data.sStr := '';

  FinderFirstCondForHtmlDocWithFrames(iDoc, integer(@Data), fGetTxtOneFrame);

  result := data.sStr;

  data.sStr := '';

end;

function GetHtmlAllFrames(pDisp: IDispatch): string;
var
  iDoc: IHtmlDocument2;

begin
  result := '';

  if not assigned(pDisp) then
    Exit;
  if not assigned((pDisp as IWebBrowser2).Document) then
    Exit;

  iDoc := (pDisp as IWebBrowser2).Document as IHtmlDocument2;

  result := GetHtmlAllFrames2(iDoc);

end;

function GetTxtAllFrames(pDisp: IDispatch): string;
var
  iDoc: IHtmlDocument2;

begin
  result := '';

  if not assigned(pDisp) then
    Exit;
  if not assigned((pDisp as IWebBrowser2).Document) then
    Exit;

  iDoc := (pDisp as IWebBrowser2).Document as IHtmlDocument2;

  result := GetTxtAllFrames2(iDoc);

end;
....

end.



возможно, что ничего не опустил... Возможно, что есть мелкие баги — но в проекте, где єто юзалось — претензий к функциональности не было..



да, в
function GetTxtAllFrames(pDisp: IDispatch): string;
function GetHtmlAllFrames(pDisp: IDispatch): string;

в качестве pDisp: IDispatch нужно передавать WB.DefaultInterface, впрочем это понятно из реализации..

удачи в борьбе с TWebBrouser-ом и com-интерфейсами...
Re[4]: Помогите пожалуйста, проблема с компонентом Webbrowse
От: ratttx  
Дата: 30.05.06 23:44
Оценка:
Здравствуйте, Ihor Osovyak.

Спасибо за код, скопировал, раскидал все, куда нужно, и у меня началась истерика )))))))))
Я таких ошибок еще не видел, которые он выдавал,
aDoer: TOneStepSearchCondForHtmlDocWithFrames — на это ругается, говорит о что то непонятное ) хотя я это закоментировал как
type
TOneStepSearchCondForHtmlDocWithFrames = function(iDoc: IHtmlDocument2; addPrm: integer): boolean;

[Error] Unit1.pas(10): Unsatisfied forward or external declaration: 'TForm1.FinderFirstCondForHtmlDocWithFrames'

ну это еще ладно... )
uses
fIEFrames; — У меня по ходу такой библиотеки дцушной нема ))))))))))))))))))))))))))

Уже смешно?
Тупой я, что сказать...
Да это еще пол беды!!!! Сейчас вообще смеяться будете! ))

Я забыл, как функциями пользоваться, а вернее как их вызывать, и результат записывать
Псле этого, я начал писать это сообщение, и наверняка до сих пор валяюсь в приступе пароноедального смеха ))
Re[5]: Помогите пожалуйста, проблема с компонентом Webbrowse
От: Ihor Osovyak Украина  
Дата: 31.05.06 08:14
Оценка:
Здравствуйте, ratttx, Вы писали:

R>Здравствуйте, Ihor Osovyak.



Читать, читать и еще раз читать, как говорил один человек.
Учебники по паскалю и делфи. Хотя бы когда не станет понятно что такое модуль, и как вызвать функцию из другого модуля. До того времени — дальнейший разговор безполезен. Да, крайне не рекомендую читать книги, где автором Архангельский.
И еще. я собственно привел два фрагмента кода. Первый фрагмент — собственно текст модуля fIEFrames, вы бы хотя бы поиском воспользовались по тексту моего постинга. Второй модуль — e0_PrimParser — функционал от которого нужно было просто задействовать в своем проекте. а не перебрасывать строчки из него в класс TForm1, сгенерированный делфийским визардом..
Да, еще подсказка — если все же хватитттерпения пару часов почитать учебник по паскалю, то обратите внимание, что в тексте модуля e0_PrimParser присутствуют строчки из точек — просто выбросте их.. я таким образом обозначал места, которые я вырезал из оригинального модуля, и которые вам не нужны.




R>Спасибо за код, скопировал, раскидал все, куда нужно, и у меня началась истерика )))))))))

R>Я таких ошибок еще не видел, которые он выдавал,
R>aDoer: TOneStepSearchCondForHtmlDocWithFrames — на это ругается, говорит о что то непонятное ) хотя я это закоментировал как
R>type
R> TOneStepSearchCondForHtmlDocWithFrames = function(iDoc: IHtmlDocument2; addPrm: integer): boolean;

R>[Error] Unit1.pas(10): Unsatisfied forward or external declaration: 'TForm1.FinderFirstCondForHtmlDocWithFrames'


R>ну это еще ладно... )

R>uses
R>fIEFrames; — У меня по ходу такой библиотеки дцушной нема ))))))))))))))))))))))))))

R>Уже смешно?

R>Тупой я, что сказать...
R>Да это еще пол беды!!!! Сейчас вообще смеяться будете! ))

R>Я забыл, как функциями пользоваться, а вернее как их вызывать, и результат записывать

R>Псле этого, я начал писать это сообщение, и наверняка до сих пор валяюсь в приступе пароноедального смеха ))




зы. я не смеялся. я плакал.. от печали.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.