| ||||||||||||||||
![]() | ||||||||||||||||
| ||||||||||||||||
![]() | ||||||||||||||||
| ||||||||||||||||
![]() |
Использование Microsoft HTML Parser для получения информации с веб-сайтов Одной из распространенных задач современного программиста можно назвать автоматизированное получение информации из Интернет с удаленных веб-сайтов и сохранение ее в БД или в виде HTML-файлов. Например, это может быть экспорт графических файлов прогноза погоды с метеорологического сайта, котировок акций с он-лайн биржи или новостей с веб-сайта какой-нибудь региональной газеты. Полученная информация может быть использована для составления годового статистического отчета и сохраняется в БД или отчета о текущем состоянии того или иного фактора и представляется в виде единой HTML-страницы для начальника фирмы, клиентов или отдела продаж. Можно назвать бесконечно много подобных примеров, но суть их сводится к одному - получение (экспорт) удаленной веб-страницы и извлечение из нее определенной части HTML-кода программными средствами. До настоящего времени возможности синтаксического анализа (фрагментации) HTML-страниц были довольно ограничены. Используя HTTP-компоненты, подобно WinInet.dll, или некоторые другие, разработанные третьими фирмами, можно получить доступ к требуемой веб-странице, а затем с помощью многочисленных строковых функций получить ее часть. Эта технология вполне работает, но далека от элегантности. Другой путь - использование архитектуры Microsoft Internet Explorer. Internet Explorer - это не одна отдельная программа, а целая коллекция компонентов, которые можно использовать при разработке своих приложений. Второе, что интересно для фрагментации HTML-страницы - это shdocvw.dll и .phtml.dll. Первый компонент содержит WebBrowser - Microsoft ActiveX control, используемый для визуального просмотра веб-страниц (главное окно Internet Explorer, отображающее веб-страницу и есть тот самый компонент WebBrowser). Второй компонент .phtml.dll, содержащий HTML parser ("parser" с англ. - синтаксический анализатор), может "разбирать" HTML-документы, содержащиеся в окне WebBrowser. Эта статья описывает основные приемы работы с Microsoft HTML Parser на примере простого приложения для экспорта котировок с веб-сайта MSN.com. Может быть вы уже использовали компонент WebBrowser для просмотра веб-страниц в ваших приложениях, но для нашего примера мы заново создадим мини-браузер, который затем будет превращен в синтаксический анализатор веб-страниц. 1. В меню File выберите New Project и создайте проект Standard EXE. Затем в меню Project выберите Components и добавьте Microsoft HTML Object Library и Microsoft Internet Controls. ![]() 2. На панели компонентов появятся компонент WebBrowser. Перетащите его на форму и добавьте TextBox и Command Button. Установите значение свойства Text у TextBox в "http://moneycentral.msn.com/" и измените свойство Caption у кнопки на "&Browse". ![]() 3. Дважды щелкните по кнопке и в появившемся окне исходного кода введите следующий код: Private Sub Command1_Click() WebBrowser1.Navigate Text1.Text End Sub
4. Сохраните и запустите программу. Нажав кнопку Browse, вы должны увидеть веб-страницу по адресу, который введен в текстовом поле. Таким образом, теперь у нас есть простой браузер для Интернет. Но это только первый шаг в создании нашего анализатора. 5. Вернемся к нашему проекту. В окне исходного кода выберем компонент WebBrowser1 и найдем событие DocumentComplete. Это событие проиходит когда веб-страница полностью загружена в окне браузера. Private Sub WebBrowser1_DocumentComplete _ (ByVal pDisp As Object, URL As Variant) End Sub Компонент WebBrowser имеет свойство Document, которое может быть типа IHTMLDocument и работать следующим образом Private Sub WebBrowser1_DocumentComplete _ (ByVal pDisp As Object, URL As Variant) Dim Doc As IHTMLDocument2 Set Doc = WebBrowser1.Document End Sub Новый тип IHTMLDocument2 имеет возможности, недоступные в IHTMLDocument. Вы можете использовать IHTMLDocument взамен IHTMLDocument2 для систем со старой версией Internet Explorer. И кроме того там есть похожий тип IHTMLDocument3, который также можно использовать, если вы знаете как он работает. Сразу заметим, что если вы просматриваете документы Word или XML, то можно объявлять переменную Doc как Document (для Word) или DOMDocument (для XML). Далее, перед тем как идти дальше, важная информация о структуре документов HTML. В отличие от XML документ HTML может быть создан с некоторой долей свободы. Например, вы сможете правильно загрузить HTML-документ, тэги (элементы разметки) которого не закрыты. Но хорошо структурированный HTML-документ обычно должен иметь следующие элементы: <HTML> <HEAD> ...специальная информация подобно <TITLE>... </HEAD> <BODY> ...элементы типа <TABLE>, <A>, <IMG> и.др... </BODY> </HTML> Эта структура подобна веткам дерева - тэги содержат другие тэги, которые, в свою очередь, содержат третьи и т.д... Более точно можно сказать, что каждый элемент включает в себя коллекцию от 0 до N элементов. Например, тэг <TABLE> (таблица) может содержать тэги <TR> (строки). Каждый тэг <TR> может включать сколько угодно <TD> (ячейка), которые в свою очередь могут включать уже другие элементы, не относяящиеся к таблицам (рисунки, текст и пр.). 6. Теперь, понимая базовую структуру HTML, продолжим работу с нашим примером. Анализируя страницу с http://moneycentral.msn.com/ присвоим второму тэгу <INPUT> на этой странице значение MSFT (лучше, если это значение будет вводится в поле Text1) и затем сделаем отправку (submit) формы. Private Sub Command1_Click() WebBrowser1.Navigate Text1.Text End Sub Private Sub WebBrowser1_DocumentComplete _ (ByVal pDisp As Object, URL As Variant) Dim Doc As IHTMLDocument2 Set Doc = WebBrowser1.Document If URL = _ "http://moneycentral.msn.com/home.asp" Then Dim Inputs As IHTMLElementCollection Set Inputs = Doc.All.tags("INPUT") Dim Element As IHTMLElement Set Element = Inputs.Item(1, 1) Dim InputElement As IHTMLInputElement Set InputElement = Element InputElement.Value = Text1.Text Doc.Forms.Item(0, 0).submit End If End Sub Здесь вы можете видеть как коллекции тэгов могут быть объявлены при помощи специфических типов. Каждый тэг может быть представлен как IHTMLElement или при помощи специального типа, зависящего от типа элемента. Например, тэг <TABLE> можно представить с помощью IHTMLTableElement (элементы таблицы) или IHTMLElement. Коллекция тэгов содержит следующие важные методы и свойства: Length - Количество элементов в коллекции. Сейчас вы можете спросить "Почему же нельзя получить требуемую информацию прямо c http://moneycentral.msn.com/scripts/webquote.dll?ipage=qd&Symbol=msft"? Да, пока это работает, но данным примером мы показываем как использовать HTML-формы в более сложных ситуациях. Если вы прямо сейчас запустите программу, то заметите, что наш пример будет бесконечно загружать одну и ту же страницу. Приложение продолжает искать форму, заполнять ее и делать submit. Поэтому каждый раз вызывается метод DocumentComplete. Для устранения этой проблемы необходимо добавить проверку в DocumentComplete, чтобы отправка формы срабатывала только один раз на нужной веб-странице. 7. Итак, программный код будет выглядеть следующим образом: Private Sub Command1_Click() WebBrowser1.Navigate Text1.Text End Sub Private Sub WebBrowser1_DocumentComplete _ (ByVal pDisp As Object, URL As Variant) Dim Doc As IHTMLDocument2 Set Doc = WebBrowser1.Document If URL = _ "http://moneycentral.msn.com/home.asp" Then Dim Inputs As IHTMLElementCollection Set Inputs = Doc.All.tags("INPUT") Dim Element As IHTMLElement Set Element = Inputs.Item(1, 1) Dim InputElement As IHTMLInputElement Set InputElement = Element InputElement.Value = Text1.Text Doc.Forms.Item(0, 0).submit ElseIf URL = _ "http://moneycentral.msn.com/scripts/ webquote.dll?ipage=qd&Symbol=" _ & Text1.Text Then Dim Tables As IHTMLElementCollection Set Tables = Doc.All.tags("TABLE") Dim Quote As IHTMLElement Set Quote = _ Tables.Item(14, 14).All.tags("TD").Item(2, 2) MsgBox Quote.innerText End If End Sub На этом заключительном этапе наш браузер превратился в некое подобие синтаксического анализатора веб-страниц. Добавим, что IHTMLElement имеет следующие возможности: innerText - Текст между открывающим и закрывающим тэгами Также заметьте, что окончательная строка получается из 11-го элемента 4-ой таблицы. Что произойдет если на MoneyCentral решат изменить раскладку страницы? Лучшей стратегией будет обращение к странице, созданной с определенной логикой. Если вы уверены, что котировки акций обычно расположены перед заголовками новостей, тогда имеет смысл искать таблицу котировок, идя назад (к началу страницы) от таблицы с новостями. Другой тактикой будет легкое изменение вашей программы-анализатора когда изменится формат запрашиваемой страницы. Один из путей сделать это - разбить единую процедуру анализа на более меньшие. В этом случае после изменения страницы можно будет обойтись либо изменением порядка вызываемых процедур, либо включением новых. Кроме того, это позволит другим программистам, использующим ваш исходный код, без труда вносить изменения пользуясь общим интерфейсом. Для этого нужно будет IHTMLDocument передавать как параметр из функции DocumentComplete в другие модули, которые будут анализировать его содержимое. Это позволит легко разбить программу на модули. И в заключение, перед тем, как вы начнете использовать свое приложение, некоторая информация для внимания. Есть много сайтов, которым безразлично, что посетители скачивают содержимое их сайта. Если вы предполагаете использовать экпортируемые данные для переиздания на своей веб-странице, то лучше, если вы будете иметь предварительное согласие с тем сайтом, с которого берете информацию. ------- |
|
![]() | ||||||||||||||||
| ||||||||||||||||
![]() | ||||||||||||||||
|