Я могу найти 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
Здравствуйте, 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...
Посмотрите мою древнюю статью на Королевстве делфи в Подземелье магов, писалась давно, но в общем то немного имеет актуальность, там немного другой подход.. Кажется, там также есть пример работы с фреймами (или это только планировал писать в продолжении, если это так — стучите еще раз, брошу пример сюда)...
R>end; R>Но есть проблема, что на сайте МНОГО ФРЕЙМОВ, и мне выдается ХТМЛ код не того, что мне нужно,
подозреваю, что Вы не учитываете того, что фреймы не обязательно все на одном уровне, а могут быть вложены друг в друга (тохоже как директории на диске, а Ваш код проходит только по коревой директории (аналогия верна в первом приближении, прошу не судить строго)
а если я пробую обратиться к фрейму как описал выше, а после воспользоваться этой процедурой, то мне выкидывает ошибку примерно такую -"Я обьявил ОЛЕэлемент и пытаюсь вытащить код ЭТОГО ЭЛЕМЕНТА(Ему все равно, что этот элемент является фреймом...)" (ovElements:= Webbrowser.OleObject.Document.frames.item(2).Document — эта фишка не работает... (((((((((((
ну об чем и речь, я уже об этом говорил..
удачи..
Re[2]: Помогите пожалуйста, проблема с компонентом Webbrowse
Большое спасибо за вашу статью, но прочитав ее я понял, на сколько я глупый.... )
Я сильно извиняюсь но не могли бы вы написать небольшой кодик на простой буттон(или ОНДОКУМЕНТкомплит), что бы он просто вынимал ХТМЛкод из всех фреймов и заносил их все в мемо... В статье, я так и не понял, как это делается, потыкался, потыкался и опять сполз на 0...
Еще раз извиняюсь за принесенные неудобства....
Re[3]: Помогите пожалуйста, проблема с компонентом Webbrowse
Здравствуйте, 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
Спасибо за код, скопировал, раскидал все, куда нужно, и у меня началась истерика )))))))))
Я таких ошибок еще не видел, которые он выдавал,
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
Здравствуйте, 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>Псле этого, я начал писать это сообщение, и наверняка до сих пор валяюсь в приступе пароноедального смеха ))