![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Доброго времени суток, господа! Появилась необходимость написать сетевое приложение для сбора веб-страниц. Постановка задачи следующая:
1)Приложение слушает на определённом порту. 2) На порт приходит клиент и говорит, допустим "HELLO" 3) По этой комманде должен создаваться объект TWebBrowser и при успехе в ответ приходит, допустим "READY" (какие либо ошибки пока не рассматриваю...) 4) Клиент посылает комманту "LOAD" с параметром, к примеру "http://ya.ru", на что этот объект должен соответственно среагировать ![]() 5) по коммандам HTML и DOCUMENT сервер должен отдать хтмл код и боди.иннер текст соответсвенно. При дисконнекте объект TWebBrowser должен уничтожится. Долго поломав голову, в качестве сервера выбрал IdTcpServer для теста в событие камманды HELLO вписал следующее: Код:
uses MSHTML, ActiveX;
...
procedure TForm1.IdTCPServer1HELO_COMMANDCommand(ASender: TIdCommand);
var
doc: IHTMLDocument2;
IE: TWebBrowser;
begin
memo1.Lines.Add('Client '+asender.Thread.Connection.Socket.Binding.PeerIP+':'+inttostr(asender.Thread.Connection.Socket.Binding.PeerPort)+' says: HELLO '+asender.UnparsedParams);
CoInitialize(nil);
IE := TWebBrowser.Create(Form1);
IE.Visible := true;
IE.enabled := true;
IE.Silent :=false;
IE.Navigate('http://ya.ru');
memo1.Lines.Add('Waiting...');
//while IE.Busy do sleep (200);}
sleep (10000);
doc := IE.Document as IHTMLDocument2;
memo1.Lines.Add('DOM');
memo1.Lines.Add(doc.body.innerText); //Тут прога вылетает с екзепшном "Access violation at address 0046CCFB in module 'Proj.exe'. Read of address 00000000"
//asender.Thread.Data := TObject(@IE);
end;
Вопрос: что я не так делаю? ![]() Последний раз редактировалось @Vorona, 26.02.2011 в 14:58. |
|
#2
|
|||
|
|||
|
Новые подробности: для теста поместил на форму 2 кнопки и TWebBrowser по событиям кнопок:
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
IE.Navigate('http://ya.ru');
end;
procedure TForm1.Button3Click(Sender: TObject);
var
doc: IHTMLDocument2;
begin
doc := IE.Document as IHTMLDocument2;
memo1.Lines.Add(doc.body.innerText);
end;Код:
procedure TForm1.IdTCPServer1HELO_COMMANDCommand(ASender: TIdCommand);
var
doc: IHTMLDocument2;
begin
memo1.Lines.Add('Client '+asender.Thread.Connection.Socket.Binding.PeerIP+':'+inttostr(asender.Thread.Connection.Socket.Binding.PeerPort)+' says: HELLO '+asender.UnparsedParams);
IE.Navigate('http://ya.ru');
end;
procedure TForm1.IdTCPServer1DOM_COMMANDCommand(ASender: TIdCommand);
var
doc: IHTMLDocument2;
begin
doc := IE.Document as IHTMLDocument2;
memo1.Lines.Add(doc.body.innerText);
end;При этом кнопки работают как надо, а по коммандам инди - вываливается экзепшн. |
|
#3
|
|||
|
|||
|
TWebBrowser - это ActiveX компонент. А для каждого клиента TIdTCPserver открывает поток. Тут то и приходит засада - для каждого нового потока надо инициализировать COM-подсистему вручную (CoInitialize, если не ошибаюсь).
Однако, весь вопрос в том - а зачем тебе TWebBrowser. Получить страничку можно и через TIdHTTP. |
|
#4
|
|||
|
|||
|
В данный момент у меня уже имеется програмулина, написанная на C#.NET, она вообще явно использует COM объект InternetExplorer.Application и собирает страницы из него. Прога жутко тормозит и жрёт оперативу (для каждого соединения открывается свой IE). Мне просто помимо исходного кода страницы нужно собирать иннер текст (то есть то, что видит пользователь, после всевозможных яваскриптов типа document.write). С IdHttp ни разу не работал, мне кажется иннер текст собрать ей не получится... А CoInitialize у меня в каждом потоке выполняется (в предыдущих постах она есть), без него прога даже не компилилась...
|
|
#5
|
|||
|
|||
|
И за каким же шишом на сервере нужен TWebBrowser ?
Это же визуальный контрол) Кто на содержимое окна браузера на стороне сервера глазеть-то будет ? Вполне достаточно класса CoHTMLDocument в составе mshtml.pas |
|
#6
|
|||
|
|||
|
Цитата:
Я попробовал чарез CoHTMLDocument. Что-то заработало, но как-то не так... Получилось что-то вроде того: Комманда HELLO: Код:
try
CoInitialize(nil);
IED := CoHTMLDocument.Create as IHTMLDocument2;
IHTTP := TIdHTTP.Create(nil);
IE_running := true;
newMsg := 'READY';
except
newMsg := 'ERROR_IE_CANNOT_START';
end;Код:
HTML := IHTTP.Get(Trim(Copy(msg, Pos(' ', msg) + 1, Length(msg)-1)));
OleVariant(IED).write(HTML);
//IED.open(Trim(Copy(msg, Pos(' ', msg) + 1, Length(msg)-1)), '_self','',true);
page_loaded := true;
newMsg := 'OK'Код:
if page_loaded then
begin
ClientSocket.Sendln(AnsiToUtf8((IED as IHtmlDocument2).body.innerText));
newMsg := 'THE_END_OF_DATA_TRANSFER';
end else newMsg := 'ERROR_PAGE_NOT_LOADED';Помогите допилить это, уже замучался с этим проэктом P.S.: додбавил IdHttp, так как c open'ом мы не сдружились, по open'у открывается IE, после чего DOM вызывает ошибку access violation |