Три функції, призначені для вилучення з HTML-документа тільки потрібної інформації. Адміністраторам систем Windows періодично доводиться займатися вилученням конкретної інформації з документів HTML. Такий документ може бути локальним файлом, сторінкою стану пристрою, підключеного до локальної мережі, звітом з бази даних, доступної через Web, або будь-який інший з тисячі типів сторінок. У кожному з цих випадків ми зазвичай стикаємося з двома проблемами використання даних. Перша з них полягає в підключенні до потрібної Web-сторінці і зчитуванні містяться в ній даних.
ARUBA INSTANT WI-FI: ПРОСТІ, ПОТУЖНІ, ДОСТУПНІ
Три функції, призначені для вилучення з HTML-документа тільки потрібної інформації
Адміністраторам систем Windows періодично доводиться займатися вилученням конкретної інформації з документів HTML. Такий документ може бути локальним файлом, сторінкою стану пристрою, підключеного до локальної мережі, звітом з бази даних, доступної через Web, або будь-який інший з тисячі типів сторінок. У кожному з цих випадків ми зазвичай стикаємося з двома проблемами використання даних. Перша з них полягає в підключенні до потрібної Web-сторінці і зчитуванні містяться в ній даних. Справа в тому, що якщо сторінка не є статичним файлом, доступним через будь-які колективні ресурси Windows або файлову систему в нашій мережі, то ми не можемо зчитувати її вміст, використовуючи такі стандартні засоби, як, наприклад, об'єкт Scripting.FileSystemObject. Крім того, для доступу до пристрою, який обслуговує цікавить Web-сторінку, може знадобитися вказати відповідні ім'я користувача та пароль. При цьому після вирішення зазначеної проблеми ми стикаємося з ще більш складним завданням: як витягти необхідну інформацію з практично "сирого" (raw) HTML?
витяг даних
Робота з запитувачем XMLHTTP ділиться на три стадії: установка з'єднання, Зробити запит на отримання відповіді. Для даного компонента відкриття з'єднання має на увазі також детальний опис його параметрів. Повний синтаксис виклику методу open об'єкта Microsoft.XMLHTTP виглядає наступним чином (в квадратних дужках наведені необов'язкові аргументи):
Тут method - строковий аргумент, що описує тип виконуваного запиту. У разі HTTP-з'єднань він зазвичай має значення "GET". Аргумент url також є строковим параметром, в якому, в разі звернення до віддалених даних, повинен повністю визначатися коректний шлях URL. При роботі з локальними файлами даний аргумент теж використовується, але в цьому випадку він являє собою повний шлях до файлу, з яким передбачається працювати (при цьому префікс file: // в описі шляху використовувати не потрібно).
Необов'язковий аргумент async служить для того, щоб вказати запитувача, чи повинен він очікувати відгуку (синхронний режим, йому відповідає значення False) або переходити до наступного рядка коду відразу після відправлення запиту (асинхронний режим - значення True). Якщо даний аргумент пропущено, то за замовчуванням береться значення True, але в розглянутому прикладі це неприпустимо, тому що після відправлення запиту необхідно, щоб сценарій дочекався відповіді, оскільки в сценарії відразу слідом за відправкою запиту виконується обробка його результатів. Отже, в даному випадку має бути встановлено значення False.
Наступні два аргументи будуть корисні в разі звернення до ресурсів з обмеженим доступом, але жорстко ставити їх в сценаріях слід з обережністю. Якщо для доступу до ресурсу повинні вказуватися ім'я користувача і пароль, то вони можуть бути задані, відповідно, у вигляді аргументів user і pass. що дозволяє уникнути помилки аутентифікації при виконанні запиту. Але якщо для доступу до потрібного ресурсу аутентифікація не вимагається, тоді ці аргументи ставити не потрібно, або можна вказати порожній рядок - або за допомогою vbNullString, або через символ подвійних лапок ( ""). Тепер у нас є вся необхідна інформація для установки з'єднання, і ми додаємо в сценарій наступний рядок:
Таким чином, ми сконфигурировали і встановили з'єднання, але сам запит ще не зробили. Для цього скористаємося методом send:
Після закінчення виконання запиту відбувається звернення до отриманих даних, для чого використовується властивість responseText запитувача:
Тепер вся сторінка цілком стала доступна в якості даних для нашого сценарію. Треба сказати, що всі мої пояснення були досить розлогими, проте сам код, який реалізує ці процедури, складається всього з чотирьох рядків. Причому ближче до закінчення статті даний код буде вбудований в функцію, після чого стане зрозуміло, як можна викликати його за допомогою одного рядка.
Видно, що в отриманих в результаті виконання запиту даних присутній значний рівень "шуму", відповідно, для виділення цікавить нас інформації цей шум повинен бути відфільтрований. Інакше кажучи, ми маємо понад 200 рядків тексту і приблизно 1250 слів, і у всій цій масі потрібно знайти тільки те слово, яке нас цікавить.
фільтрація шумів
Було б добре мати механізм для швидкого відсіювання цих шумів. В принципі, теги HTML і XML можна відфільтрувати, завантаживши отримані дані в об'єкт XmlDocument або HtmlDocument, після чого виконати запит, який повертає тільки текст документа. Однак якщо дані не цілком відповідають вимогам використовуваного об'єкта, це може привести до проблем.
В цілому, на мій погляд, в даному підході більше ризику, ніж переваг, і ось чому. Об'єкт XmlDocument може працювати з конфигурационной сторінкою нашого маршрутизатора, але якщо вона не буде мати повністю коректний формат документа XML, то процес обробки дасть збій. Що ж стосується об'єкта HtmlDocument, то, в принципі, він надає прекрасні можливості фільтрації небажаного вмісту, але з ним пов'язаний і зі значним ризиком, оскільки робота нашого сценарію буде перервана. Якщо сторінка містить нерегулярні дані - причому це може бути і такий вміст, яке без помилок обробляється в IE - то в цьому випадку об'єкт HtmlDocument може згенерувати вікно помилки, що блокує інтерфейс. Причому сам сценарій може, тим не менш, продовжити роботу на цій сторінці з віртуальним документом, що в результаті призведе до нестабільної роботи.
Отже, спочатку потрібно створити посилання на механізм роботи з регулярними виразами в VBScript. Оскільки нас цікавить фрагмент може бути виявлений в декількох рядках витягнутих даних, ми повинні задіяти властивості Multiline і Global:
Перший крок в процесі виділення цільової інформації полягає у видаленні із загального обсягу даних всіх тегів HTML. Оскільки теги HTML і XML завжди починаються і закінчуються символами кутових дужок (<>), Їх можна легко ідентифікувати, застосувавши наступний шаблон (pattern):
Ті, хто має досвід роботи з регулярними виразами, вже зрозуміли, що цей шаблон визначає пошук рядків, що починаються символом "". Однак багатьох може збити з пантелику частина виразу, що знаходиться всередині кутових дужок (тобто [^>] +). Коли в вираженні використовується символ вставки (^), укладений між символами набору знаків ([) і (]), це наказує виявляти збіги з будь-якими символами, що не входять в даний набір. Знак плюс (+) більш звичний для тих, хто користується регулярними виразами; він означає виявлення збігів з послідовністю з одного або більше знаків з даного набору. Отже, вираз [^>] + позначає виявлення збігу з будь-яким символом, крім символу>. Таким чином, повний опис шаблону] +> визначає виявлення будь-яких послідовностей, що починаються з символу. але не містять символ>.
Після того як всі теги були виявлені, залишається просто видалити їх. Для цього використовуємо регулярний вираз в режимі заміни, підставляючи замість тегів порожні рядки:
Якщо поглянути на стандартну Web-сторінку після виконання цієї операції, зауважимо, що на ній залишилася значна кількість даних, причому більша їх частина є порожніми, тобто комбінацією символів табуляції, стандартних прогалин і символів закінчення рядка. Також зустрічаються і спеціальні символи HTML. І хоча в даному тут прикладі Web-сторінки конфігурації маршрутизатора їх наявність не є принциповим, проте, має сенс очистити сторінку від одного з цих символів, оскільки це дозволить спростити подальшу процедуру пошуку: мова йде про спеціальний символ нерозривного пробілу, зазвичай позначається на Web-сторінках як "". В даному випадку для заміни цього символу можна знову скористатися можливостями регулярних виразів, але простіше використовувати функцію заміни символів з VBScript. За допомогою наведеної нижче команди кожен з цих спецсимволов буде замінений символом пробілу:
Заключний крок загальної процедури очищення полягає в тому, щоб перетворити все зустрічаються в наших даних послідовності порожніх знаків в поодинокі символи пробілів. Це потрібно для того, щоб в процесі пошуку рядка не доводилося визначати, скільки недрукованих символів (і якого типу) відокремлюють одне слово від іншого. Для перетворення пустот в поодинокі символи пробілів задамо новий шаблон регулярного виразу, що забезпечує пошук збігів з одним або більше порожнім символом будь-якого типу:
Потім замінимо кожне з запропонованих варіантів символом одиничного пробілу:
значна інформація
Велика частина залишилася роботи буде своєрідною для кожної конкретної Web-сторінки, з якої потрібно витягти інформацію, проте в більшості випадків вона може бути виконана за допомогою двох-трьох рядків коду. Більшість завдань мережевого моніторингу та управління по суті зводяться до повторюваним процедурам доступу до багатьох сторінок, тому незначні тимчасові витрати, необхідні для створення програмного інструменту для отримання потрібної інформації в подальшому швидко виправдають себе.
і розташуємо її зліва від значення 256.261.381.125.
Наявність цих функцій дозволить спростити процес адаптації даного сценарію під конкретні завдання. Зокрема, якщо ви маєте досвід отримання потрібного матеріалу зі сторінок за допомогою регулярних виразів і вважаєте за краще робити це будь-яким звичним способом, тоді ви можете користуватися тільки функцією GetWebXml для вилучення даних, а потім обробляти їх потрібним чином. Якщо ж ви віддаєте перевагу використовувати готові рішення, але маєте деякі специфічні вимоги (наприклад, необхідно витягти не одну, а кілька рядків), то в цьому випадку можна задіяти функцію CleanTaggedText і ігнорувати функцію GetSubString. І, нарешті, якщо з усієї сторінки потрібно витягти тільки один рядок і отримати відповідний унікальний текст перед самим значенням і після нього, тоді можна використовувати всі три функції - так, як це роблю я.
Лістинг 1. Сценарій для добування інформації з Web-сторінки.
Поділіться матеріалом з колегами і друзями