Поиск по блогу

Показаны сообщения с ярлыком IHTMLDocument2. Показать все сообщения
Показаны сообщения с ярлыком IHTMLDocument2. Показать все сообщения

вторник, 27 апреля 2010 г.

Работа с комбобоксами (SELECT) в TWebbrowser

В интернете достаточно материала о том, как работать с элементом SELECT в TWebBrowser. У себя на блоге я мельком уже задевала уже этот вопрос, но вот решила написать отдельный пост.
Тем, для кого этот материал вновинку, сначала советую ознакомиться со статьями:

1. TWebBrowser, OleObject и его свойства.
2. Работа с формами в TWebBrowser.

Обычно я делаю так: сначала ищу на форме нужный селект по имени (тип искомого объекта - IHTMLSelectElement (не забудьте подключить библиотеку MSHTML)). Селект можно находить по id или по name, в зависимости от требований. Вот пример функции, возращающей требуемый элемент (проверяется и по id, и по name):

function FindCBByName(CBName: String) : IHTMLSelectElement;

function TMainF.FindCBByName(CBName: String): IHTMLSelectElement;
var
i : integer;
DocSelect : IHTMLElementCollection;
DocElement : IHtmlElement;
Doc : IHTMLDocument2;
begin
Result := nil;
WB.Document.QueryInterface(IHTMLDocument2, Doc);
DocSelect := Doc.all.tags('SELECT') as IHTMLElementCollection;

for i := 0 to DocSelect.length-1 do
begin
DocElement := DocSelect.Item(i, 0) as IHtmlElement;
if (UpperCase(DocElement.id) = UpperCase( CBName )) or
(UpperCase(DocElement.getAttribute('name',0)) = UpperCase( CBName )) then
begin
Result := DocElement as IHTMLSelectElement;
exit;
end;
end;
end;


В случае, если объект не найден, возвращается nil. В данном примере у меня привязка к объекту TWebBrowser (WB) на форме. Можно избавиться от нее, добавив TWebBrowser в качестве параметра функции (я так обычно и делаю).

Когда элемент найден, в нем надо будет выбрать значение. В зависимости от задачи, требуется обычно выбрать option по тексту или по value.

В качестве примера привожу процедурку, которая уже "светилась" в статьях на этом блоге.

вторник, 6 января 2009 г.

Создание карты блога на blogspot.com своими руками

Это очередной простенький пример применения парсинга. Даже не столько парсинга, сколько работы с объектной моделью браузера.

Чтобы создать карту блога на blogspot.com (я рассматриваю в качестве примера свой лытдыбровый блог), можно воспользоваться головой и данными из виджета "Архив блога". Изучим код страницы. Виджет оформлен как div с id='ArchiveList'. Внутри дива — ненумерованный список. Элементы UL, группирующие ссылки по месяцам, имеют classname='posts'. Сразу становится понятно, что для создания карты сайта достаточно будет выбрать все элементы LI, находящиеся внутри упомянутых UL. Это делается в два счета при работе с MSHTML.

Обработчик кнопки "Start":

procedure TBlogspotSiteMapF.btnStartClick(Sender: TObject);
var
Doc : IHTMLDocument2;
DocAll,
DocLi : IHTMLElementCollection;
ParentElement,
DocElement : IHtmlElement;

i : integer;
begin
WebBrowser.Navigate(edtURL.Text);
while WebBrowser.ReadyState <> READYSTATE_COMPLETE do
begin
Application.ProcessMessages;
end;

Doc := WebBrowser.Document as IHTMLDocument2;
if Assigned(Doc) then
begin
DocAll := Doc.all;
DocLi := DocAll.Tags('LI') as IHTMLElementCollection;

for i := 0 to DocLi.length-1 do
begin
DocElement := DocLi.Item(i, 0) as IHtmlElement;
ParentElement := DocElement.parentElement;

if ParentElement.className = 'posts' then
Memo.Lines.Add(DocElement.innerHTML);
end;
end;
end;


В результате получаем такую картину:



После парсинга первоначального списка обнаружились некоторые ньюансы. А именно: записи, имеющие слишком длинные названия, обрезаются по количеству символов (на рисунке для примера я обвела красным ссылку и пример заголовка одного из таких сообщений). Но это не страшно и вопрос решается очень просто: надо скачать страницу по ссылке и достать из html-кода полный заголовок (внутри h3 с classname = 'post-title entry-title'). В принципе, я думаю, что данная процедура необязательна, так как карты сайтов используются в основном поисковиками. Тем более, что если записей в блоге очень много — это мероприятие может оказаться затратным :)



Чтобы быть в курсе обновлений блога, можно подписаться на RSS.

суббота, 30 августа 2008 г.

Объектная модель браузера (DOM в веб-браузерах)

Немного об объектной модели браузера. Почему немного? Потому что этот блог посвящен все-таки созданию парсеров, а не изучению отдельных вопросов программирования.

В Википедии:
DOM (от англ. Document Object Model — «объектная модель документа») — это не зависящий от платформы и языка программный интерфейс, позволяющий программам и скриптам получить доступ к содержимому документов, а также изменять содержимое, структуру и оформление документов.

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

К объектам можно обращаться по id, по номеру в массиве (например, если надо перебрать все элементы одинакового типа).

Я бы посоветовала взять в руки какой-нибудь толстенный спровочник по JavaScript, например. И просмотреть раздел, посвященный объектной модели браузера. В свое время я так и делала. Необязательно знать и помнить все объекты, свойства и методы — важно оценить возможности и прикинуть, для чего все это может пригодиться. Тем, кто уже изучал JavaScript, будет немного легче.

Так, сейчас немного о том, как работать с объектной моделью в Delphi, используя рассмотренный в предыдущем посте компонент TWebBrowser.

Существует интерфейс IHTMLDocument2, который позволяет с легкостью это делать. А можно напрямую через OleObject. Например, если в html-документе, заруженном в WebBrowser, есть, допустим, инпут с id='message', то код:
WebBrowser.OleObject.document.getElementById('message').Value := 'Привет!';
запишет в этот инпут строку "Привет!".

А код:
  ovElements := WebBrowser1.OleObject.Document.Forms.Item(0).Elements;
for i := 0 to (ovElements.Length-1) do
if (AnsiUpperCase(ovElements.Item(i).tagName) = 'INPUT') then
if (AnsiUpperCase(ovElements.Item(i).type) = 'SUBMIT') or
(AnsiUpperCase(ovElements.Item(i).type) = 'BUTTON') then
if (ovElements.item(i).Value = 'Send') then
ovElements.Item(i).Click;
переберет все элементы первой по счету формы страницы, найдет в ней кнопку, на которой будет написано "Send" и сымитирует ее нажатие.

Как видите, объектная модель — очень полезная и удобная штука. Хотя основное ее применение — не парсинг, а автоматизация регистраций, заполнения форм и так далее. Чтобы показать, насколько она может быть полезна, в следующих постах приведу пример разработки и создания небольшой утилиты для автоматизации добавления вашей RSS-ленты в RSS-агрегаторы.

Поделиться