Как вы уже поняли, работать с DOM html-страницы гораздо удобнее, чем работать непосредственно с html с помощью регулярных выражений. Но компонент TWebBrowser на форме нам совсем не нужен. Можно просто скачать страницу, а потом создать экземпляр класса coHTMLDocument и работать с ним.
Код, иллюстрирующий сказанное:
uses
... MSHTML, UrlMon, activex;
function DownloadFile(SourceFile, DestFile: string): Boolean;
begin
try
Result := UrlDownloadToFile(nil, PChar(SourceFile), PChar(DestFile), 0,
nil) = 0;
except
Result := False;
end;
end;
procedure TMainF.cxButton1Click(Sender: TObject);
var
sFileName : string;
i: integer;
v : OleVariant;
Doc : IHTMLDocument2;
DocAll,
DocA : IHTMLElementCollection;
AParentElement,
DocElement : IHtmlElement;
SLBody : TStringList;
begin
// загружаем страницу
try
SLBody:=TStringList.Create;
sFileName:=ExtractFilePath(Application.ExeName) + 'cache.txt';
if DownloadFile(RegionURL,sFileName) then
SLBody.LoadFromFile(sFileName);
DeleteFile(sFileName);
Doc := coHTMLDocument.Create as IHTMLDocument2;
if Doc = nil then
begin
ShowMessage('Ошибка создания IHTMLDocument2');
exit;
end;
v := VarArrayCreate([0,0],VarVariant);
v[0] := SLBody.Text;
Doc.write(PSafeArray(TVarData(v).VArray));
DocAll := Doc.all;
DocA := DocAll.Tags('A') as IHTMLElementCollection;
for i := 0 to DocA.length-1 do
begin
DocElement := DocA.Item(i, 0) as IHtmlElement;
AParentElement := DocElement.parentElement;
if LowerCase(AParentElement.tagName) = 'li' then
begin
S := DocElement.innerHTML + ' ['+ DocElement.getAttribute('href',0) +']';
mRequest.Lines.Add(S);
end;
end;
finally
begin
SLBody.Free;
Doc.Close;
Doc := nil;
end;
end;
end;
Как видите, все просто.
В примере показана работа с атрибутом href ссылки. Отличие от работы с атрибутом href ссылок кода, предварительно загруженного в TWebBrowser, будет состоять в том, что относительные ссылки отражаются немного по-другому. Например, если в коде есть ссылка "href=/?region=1", то результатом кода
DocElement.getAttribute('href',0)
будет "about:blank/?region=1". Это связано с тем, что страницей по умолчанию объекта является about:blank. Но это не страшно. Можно их обработать и привести к нужному виду.
Удачных разработок!
___
А сама я помимо программирования решила попробовать поработать с биржей ссылок Nahaa.ru. Если еще не знаете, что это такое и с чем это едят, то можете почитать историю о моем освоении этого сервиса.
Чтобы быть в курсе обновлений блога, можно подписаться на RSS.
Доброго времени суток, Маша.
ОтветитьУдалитьДа интересный блог. Все бы хорошо, только заинтересовало это
"Но это не страшно. Можно их обработать и привести к нужному виду."
Так как вы это обрабатываете??
Да тут уже можно просто применить элементарные делфёвые функции работы со строками — просто заменить about:blank на нужную строку. Например:
ОтветитьУдалитьStringReplace(DocElement.getAttribute('href',0),'about:blank','http://yandex.ru',[]);
Предпоследний аргумент (т.е. строка, на которую надо заменить) берется или вычисляется в зависимости от конкретной задачи. Например, если в коде ссылка всегда относительно корня — это самый элементарный случай. Если такая ссылка в коде скрипта, запускаемого из подкаталога — там уже нужно смотреть и "вычленять" нужную часть строки из адреса загруженной страницы.
Может, немного несвязно объяснила, но, по-моему, выполнение этих преобразований не должно вызывать вопросов :)
Доброго дня, Маша :)
ОтветитьУдалитьСпасибо за ответ. Про реплейс, это конечно красиво, но не то немножко (до этого я и сам допер).
Дело в том, что у меня например, страничка сохраняется в какой-то каталог. А вместо about:blank. D:/// или другое имя диска.
Т.е. в итоге немного геммороидально получается заменять реплейсом.
Вот я и подумал, может есть какая-то настройка или педалька, которая предотвращает преобразование ссылки.
И вообще, что за безобразие в коде одна ссылка, а возвращается какие-то локальные настройки... :)
============
Дополнение.
Сейчас делаю так (мне не очень нравится):
1. какачаю с использованием Indy html-ку;
2. открываю её в WebBrowser;
3. работаю с DOM-документа;
Мне понравился ваш метод. Быстрей и правильней.
Но! При открытие в STtringList все русские символы заменяются кракозябрами.
После некоторого времени, дошел, что страница с кодировкой UTF-8 а значит и строки нужно преобразовать из UTF-8 в Ansi.
Функция: Utf8ToAnsi - может кому-то пригодится.
Про глобальную настройку - не знаю, не попадалась такая :) А функцией Utf8ToAnsi регулярно пользуюсь, и в блоге она упоминалась. Но лишнее упоминание не повредит)) Спасибо за комментарий! :)
ОтветитьУдалитьМне всё же как-то проще грузить страничку в WebBrowser. А если не хватает места на форме...просто прячу его с глаз долой. Конечно кривенько получатся, но мне не мешает :)
ОтветитьУдалитьВлад, это вопрос привычки :)
ОтветитьУдалитьМария, здравствуйте.
ОтветитьУдалитьПодскажите, если можете, такой момент: нужно загружать страницу, причем так, чтобы работали все банеры, счетчики посещений и так далее. При этом нужно реализовать многопоточную работу. Пробовал загружать, как обычно, через TidHttp, но счетчики не учитывают такую загрузку. С WebBrowser вроде работает, но с потоками пока не получается. Поэтому вопрос, описанный в статье способ будет работать как полноценный WebBrowser, но при этом можно будет нормально запускать в отдельном потоке?
Заранее благодарю за ответ.
А как в этом случае отключить ошибки выполнения скриптов?
ОтветитьУдалитьАнонимный, а что, они выскакивают? Я не сталкивалась, подсказать не могу.
ОтветитьУдалить