обнаружение изменения веб-страницы - PullRequest
0 голосов
/ 23 апреля 2011

В настоящее время я делаю свой проект / диссертацию за последний семестр, и я подумал сделать это для "обнаружения изменений веб-страницы в сети". Я прочитал две статьи на эту тему, но у меня есть некоторые заблуждения

1. в документе под названием

Усовершенствованный алгоритм обнаружения изменений веб-страниц с приложением для ускорения транскодирования мобильных веб-страниц 1

написано

сначала генерировать поддеревья из документов HTML, где каждому поддереву присваивается метка в соответствии с содержимым его тега.

Мой вопрос здесь, как генерировать поддеревья из документов HTML ?? какая техника для этого. и следующий вопрос, что он говорит, «ставя оценку в соответствии с содержимым своего тега».

2. пожалуйста, посмотрите на изображение здесь !! Общая схема предлагаемого подхода

В поле «Рассчитать большинство похожих поддеревьев» как выполняется сопоставление ?? в другом документе, озаглавленном

Эффективная система обнаружения изменений веб-страниц на основе оптимизированного венгерского алгоритма [2]

Для сопоставления используется венгерский алгоритм, строка цитируется из статьи под названием

Быстрый подход к обнаружению изменений веб-страниц HTML, основанный на хешировании и сокращении числа вычислений подобия [3]

подход в [2] использует венгерский алгоритм O (N 3 ) для вычисления максимального взвешенного соответствия на взвешенном двудольном графе и имеет время выполнения в O (N 2 * 1042) * x N 1 3 ), где N 1 и N 2 - соответственно количество узлов на старой странице и на новой (измененной) странице . »Мой вопрос: как формируются поддеревья, почему добавляются веса и как они добавляются?

Спасибо, что прочитали мои вопросы / недоразумения, мне действительно нужна помощь, и скоро, пожалуйста, кто-нибудь поможет мне с этим, я буду всегда благодарен.

Ответы [ 2 ]

0 голосов
/ 15 июня 2013

Я думаю, что у меня действительно простой и быстрый способ сделать это.

Я недавно написал и выпустил jqgram для вычисления расстояния редактирования дерева аппроксимация с простым в использовании API длясравнение DOM-подобных структур, JSON-структур или древовидных структур вашего собственного дизайна:

https://github.com/hoonto/jqgram

На основе оригинальной статьи: http://www.vldb2005.org/program/paper/wed/p301-augsten.pdf Изначально портировано из реализации Python: https://github.com/Sycondaman/PyGram

Модуль аппроксимации расстояния редактирования дерева jqgram реализует алгоритм PQ-Gram для приложений как на стороне сервера, так и на стороне браузера;O (n log n) время и O (n) пространство, где n - количество узлов.Аппроксимация PQ-Gram намного быстрее, чем получение истинного расстояния редактирования с помощью Zhang & Shasha, Klein, Guha или других, которые предоставляют алгоритмы истинного расстояния редактирования, которые работают в лучшем случае O (n ^ 2) или O (n ^ 3) в зависимости отпо какому алгоритму вы смотрите.

Вот начало того, как я буду использовать jqgram для вашей конкретной задачи, которую я взял прямо из README на github.Чтобы ответить на один из ваших вопросов, вы можете использовать DOM в качестве своей собственной древовидной структуры в библиотеке, такой как jQuery (как показано ниже), или реплицировать ее или сгенерировать ее из строки html в Cheerio или из его базовой библиотеки синтаксического анализа HTML или любой их комбинации.(jqgram предоставляет вам эту гибкость).В этом примере сравнивается DOM на текущей странице с представлением Cheerio, сгенерированным из строки - вашей известной ссылки.

// This could probably be optimized significantly, but is a real-world
// example of how to use tree edit distance in the browser.

// For cheerio, you'll have to browserify, 
// which requires some fiddling around
// due to cheerio's dynamically generated 
// require's (good grief) that browserify 
// does not see due to the static nature 
// of its code analysis (dynamic off-line
// analysis is hard, but doable).
//
// Ultimately, the goal is to end up with 
// something like this in the browser:
var cheerio = require('./lib/cheerio');

// But you could use jQuery for both sides of this comparison in which case your
// lfn and cfn callback functions become the same for both roots. 

// The easy part, jqgram:
var jq = require("../jqgram").jqgram;

// Make a cheerio DOM:
var html = '<body><div id="a"><div class="c d"><span>Irrelevent text</span></div></div></body>';

var cheeriodom = cheerio.load(html, {
    ignoreWhitespace: false,
    lowerCaseTags: true
});

// For ease, lets assume you have jQuery laoded:
var realdom = $('body');

// The lfn and cfn functions allow you to specify
// how labels and children should be defined:
jq.distance({
    root: cheeriodom,
    lfn: function(node){ 
        // We don't have to lowercase this because we already
        // asked cheerio to do that for us above (lowerCaseTags).
        return node.name; 
    },
    cfn: function(node){ 
        // Cheerio maintains attributes in the attribs array:
        // We're going to put id's and classes in as children 
        // of nodes in our cheerio tree
        var retarr = []; 
        if(!! node.attribs && !! node.attribs.class){
            retarr = retarr.concat(node.attribs.class.split(' '));
        }
        if(!! node.attribs && !! node.attribs.id){
            retarr.push(node.attribs.id);
        }
        retarr = retarr.concat(node.children);
        return  retarr;
    }
},{
    root: realdom,
    lfn: function(node){ 
        return node.nodeName.toLowerCase(); 
    },
    cfn: function(node){ 
        var retarr = [];
        if(!! node.attributes && !! node.attributes.class && !! node.attributes.class.nodeValue){
            retarr = retarr.concat(node.attributes.class.nodeValue.split(' '));
        }
        if(!! node.attributes && !! node.attributes.id && !! node.attributes.id.nodeValue) {
            retarr.push(node.attributes.id.nodeValue);
        }
        for(var i=0; i<node.children.length; ++i){
            retarr.push(node.children[i]);
        }
        return retarr;
    }
},{ p:2, q:3, depth:10 },
function(result) {
    console.log(result.distance);
});

Обратите внимание, что параметры lfn и cfn указывают, как каждое дерево должно определять имена меток узлов имассив children для каждого корня дерева независимо, так что вы можете сравнить DOM с объектом JSON или чем-то еще, что использует другую семантику для определения дочерних и меток узлов.Также обратите внимание, что в этом примере я использую атрибут класса сущности DOM, разделяя его на отдельные классы и идентификатор самого узла DOM как непосредственных дочерних элементов узла, чтобы прояснить, являются ли два дерева очень похожими или очень разными,Вы можете расширить это, чтобы включить ваши собственные атрибуты.Или вы можете также изменить функции lfn для каждого дерева, чтобы включить идентификатор в метку, например «tagname: id» - это зависит от вас и изменит работу алгоритма - возможно, что-то интересное для исследования в вашем исследовании.

Таким образом, чтобы подвести итог, все, что вам нужно сделать, это предоставить эти функции lfn и cfn вместе с каждым корнем, а jqgram сделает все остальное, вызывая функции lfn и cfn для построения деревьев.

Алгоритм PQ-Gram, реализованный jqgram, предоставит расстояние редактирования в виде числа от нуля до единицы, и следует отметить, что значение нуля не обязательно указывает на абсолютное равенство, только то, что два дерева оченьаналогичный.Если вам нужно определить, действительно ли два очень дерева, как определено с помощью jqgram, действительно идентичны, вы можете использовать Чжан и Шашу, но использование jqgram для получения метрики сэкономит вам массу вычислений, которые становятся чрезвычайно сложными.критически важен в клиентских браузерных приложениях, где производительность конечного пользователя явно важна.

Надеюсь, это поможет!

0 голосов
/ 23 апреля 2011

Первое может быть достигнуто с помощью Java Document Object Model (DOM) API. Модель DOM не очень быстрая и не эффективна с точки зрения памяти, но она почти идеально соответствует вашим потребностям.

Уже есть парсеры HTML-to-DOM, лично я рекомендую вам Cobra HTML рендер и парсер . Вам не нужны его функции рендеринга, но у него есть отдельный и довольно простой в использовании механизм синтаксического анализа - просто создайте новый DocumentBuilderImpl и передайте поток ввода содержимого страницы или URL-адрес страницы этому методу parse().

По второму вопросу рассмотрим так называемые «алгоритмы подобия деревьев», например, в этот

...