Источник: http://habrahabr.ru/blogs/data_mining/99918/
Web Mining – это процесс извлечения данных из веб-ресурсов, который, как правило, имеет больше практическую составляющую нежели теоретическую. Основная цель Web Mining – это сбор данных (парсинг) с последующим сохранением в нужном формате. Фактически, задача сводится к написанию HTML парсеров, и как раз об этом поговорим более детально.
Есть несколько подходов к извлечению данных:
Рассмотрим все подходы более детально.
Этот подход основывается на анализе DOM дерева. Используя этот подход, данные можно получить напрямую по идентификатору, имени или других атрибутов элемента дерева (таким элементом может служить параграф, таблица, блок и т.д.). Кроме того, если элемент не обозначен каким-либо идентификатором, то к нему можно добраться по некоему уникальному пути, спускаясь вниз по DOM дереву, например:
body -> p[10] -> a[1] -> текст ссылки
или пройтись по коллекции однотипных элементов, например:
body -> links -> 5 элемент -> текст ссылки
Достоинства этого подхода:
Недостатки такого подхода:
Этот подход можно использовать вместе с библиотекой Microsoft.mshtml, которая, по сути. является core элементом в Internet Explorer.
Data Extracting SDK использует Microsoft.mshtml для анализа DOM дерева, но является «надстройкой» над библиотекой для удобства работы:
UriHtmlProcessor proc =
new
UriHtmlProcessor(
new
Uri
(
"http://habrahabr.ru/new/page1/"
));
proc.Initialize();
var
links =
from
l
in
proc.Links
where
l.Class ==
"topic"
&& EndsWithInt(l.Href) ==
true
select
new
ResultItem{
Link = l.Href,
TopicName = l.Text.ToWindows1251()
};
* This source code was highlighted with
Source Code Highlighter
.
Следующим эволюционным этапом анализа DOM дерева является использования XPath – т.е. путей, которые широко используются при парсинге XML данных. Суть данного подхода в том, чтобы с помощью некоторого простого синтаксиса описывать путь к элементу без необходимости постепенного движения вниз по DOM дереву. Данный подход использует всеми известная библиотека jQuery и библиотека HtmlAgilityPack:
HtmlDocument doc =
new
HtmlDocument();
doc.Load(
"file.htm"
);
foreach
(HtmlNode link
in
doc.DocumentElement.SelectNodes(
"//a[@href"
])
{
HtmlAttribute att = link[
"href"
];
att.Value = FixLink(att);
}
doc.Save(
"file.htm"
);
* This source code was highlighted with
Source Code Highlighter
.
Несмотря на то, что этот подход нельзя применять для написания серьезных парсеров, я о нем немного расскажу.
Иногда данные отображаются с помощью некоторого шаблона (например, таблица характеристик мобильного телефона), когда значения параметров стандартные, а меняются только их значения. В таком случае данные могут быть получены без анализа DOM дерева, а путем парсинга строк, например, как это сделано в Data Extracting SDK:
Данные:
Компания: Microsoft
Штаб-квартира: Редмонд
Код:
string
data =
"<p>
Компания
: Microsoft</p><p>
Штаб
-
квартира
:
Редмонд
</p>"
;
string
company = data.GetHtmlString(
"
Компания
: "
,
"</p>"
);
string
location = data.GetHtmlString(
"
Штаб
-
квартира
: "
,
"</p>"
);
// output
// company = "Microsoft"
// location =
"
Редмонт
"
* This source code was highlighted with
Source Code Highlighter
.
Использование набора методов для анализа строк иногда (чаще – простых шаблонных случаях) более эффективный чем анализ DOM дерева или XPath.
Очень часто видел, когда HTML полностью парсили с помощью регулярных выражений. Это в корне неверный подход, так как таким образом можно получить больше проблем, чем пользы.
Регулярные выражения необходимо использоваться только для извлечения данных, которые имеют строгий формат – электронные адреса, телефоны и т.д., в редких случаях – адреса, шаблонные данные.
Еще одним неэффективным подходом является рассматривать HTML как XML данные. Причина в том, что HTML редко бывает валидным, т.е. таким, что его можно рассматривать как XML данные. Библиотеки, реализовавшие такой подход, больше времени уделяли преобразованию HTML в XML и уже потом непосредственно парсингу данных. Поэтому лучше избегайте этот подход.
В данный момент визуальный подход находится на начальной стадии развития. Суть подхода в том, чтобы пользователь мог без использования программного языка или API «настроить» систему для получения нужных данных любой сложности и вложенности. О чем-то похожем (правда применимым в другой области) – методах анализа веб-страниц на уровне информационных блоков, я уже писал. Думаю, что парсеры будущего будут именно визуальными.
Проблемы при парсинге HTML данных – использование Javascript / AJAX / асинхронных загрузок очень усложняют написание парсеров; различные движки для рендеринга HTML могут выдавать разные DOM дерева (кроме того, движки могут иметь баги, которые потом влияют на результаты работы парсеров); большие объемы данных требуют писать распределенные парсеры, что влечет за собой дополнительные затраты на синхронизацию.
Нельзя однозначно выделить подход, который будет 100% применим во всех случаях, поэтому современные библиотеки для парсинга HTML данных, как правило, комбинируют, разные подходы. Например, HtmlAgilityPack позволяет анализировать DOM дерево (использовать XPath), а также с недавних пор поддерживается технология Linq to XML. Data Extracting SDK использует анализ DOM дерева, содержит набор дополнительных методов для парсинга строк, а аткже позволяет использовать технологию Linq для запросов в DOM модели страницы.
На сегодня абсолютным лидером для парсинга HTML данных для дотнетчиков является библиотека HtmlAgilityPack, но ради интереса можно посмотреть и на другие библиотеки.