优化算法来比较两个URL的模板

时间:2013-03-30 11:54:04

标签: javascript jquery algorithm templates jsoup

已编辑,请再读一遍,因为我添加了一些我的作品

我的任务是比较两个URL的模板。我准备好了我的算法。但是需要花费太多时间才能给出最终答案。

我使用 Jsoup Selenium

Java 中编写了我的代码

此处,模板表示任何页面显示其内容的方式。

示例: -

任何购物网站都有任何鞋子的页面,其中包含

Images in the left.
Price and Size in the right.
Reviews in the bottom.

如果两个URL是任何特定产品,则返回“两者都来自相同模板”。例如,this linkthis link具有相同的模板。

如果一个网址显示任何产品而另一个网址显示任何类别,则显示“不匹配”。 例如,this linkthis link来自不同的模板。

我认为这个算法需要一些优化,这就是我在这个论坛上发布这个问题的原因。

我的算法

  1. 抓取,解析两个输入网址并制作DOM trees
  2. 然后,如果任何页面包含UL和TABLE,则删除该标记。我这样做是因为,可能是两个页面包含不同数量的项目。
  3. 然后,我计算两个URL中的标签数量。比如,initial_tag1,initial_tag2。
  4. 然后,我开始删除在相应页面上具有相同位置的标记以及相同的Id及其下面的子树,如果该树的节点数少于10个。
  5. 然后,我开始删除在相应页面上具有相同位置的标签以及相同的类名及其下面的子树,如果该树的节点数小于10 ..
  6. 然后,如果该树的节点数少于10,我开始删除没有Id,No Class名称及其下面子树的标签。
  7. 步骤4,5,6具有(N * N)复杂度。这里,N是标签的数量。 [这样,每一步DOM树都会收缩]
  8. 当它从这个递归出来时,我检查了final_tag1和final_tag2。
  9. 如果final_tag1和final_tag2小于initial_tag1 *(0.2)和initial_tag2 *(0.2),那么我可以Two URL matched,否则not
  10. 我对这个算法有很多想法,我发现从DOM树中删除节点是一个非常缓慢的过程。这可能是减慢此算法速度的罪魁祸首。

    我从一些极客那里讨论过,

      

    他们说每个标签使用一个分数而不是删除它们,然后添加它们,>在最后返回(得分我得)/(cumulativePoints)或类似的东西,并在   你决定两个URL是相似与否的基础。

    但我不明白这一点。那么你能解释一下这个极客的说法吗,或者你能否给出任何其他优化的算法来有效地解决这个问题。

    提前致谢。寻找你的回应。

2 个答案:

答案 0 :(得分:2)

为了比较网页,基本上有两种方式,快速和慢速:

  1. 比较网址:快速
  2. 比较DOM:慢(和复杂)
  3. 在您的情况下,前两个项似乎与类似的正则表达式匹配,并且类别与另一个正则表达式匹配。

    这是一个简短的JAVA解决方案

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class TestRegexp {
    public static void main(String[] args) {
        String URL_ITEM_1 = "http://www.jabong.com/Puma-Flash-Ind-Black-Running-Shoes-187831.html";
        String URL_ITEM_2 = "http://www.jabong.com/Lara-Karen-Full-Sleeve-Black-Polyester-Top-With-Cotton-Lace-196636.html";
        String URL_CATEGORY_1 = "http://www.jabong.com/kids/shoes/floaters/";
        String URL_CATEGORY_2 = "http://www.jabong.com/women/clothing/womens-tops/";
    
        Pattern itemPattern = Pattern.compile("http://www\\.jabong.com/([\\w\\p{Punct}\\d]+)\\.html");
        Pattern categoryPattern = Pattern.compile("http://www\\.jabong.com/([\\w\\p{Punct}]+/)+");
    
        System.out.println("Matching items");
        Matcher matcher = itemPattern.matcher(URL_ITEM_1);
        System.out.println(matcher.matches());
        matcher = itemPattern.matcher(URL_ITEM_2);
        System.out.println(matcher.matches());
        matcher = itemPattern.matcher(URL_CATEGORY_1);
        System.out.println(matcher.matches());
        matcher = itemPattern.matcher(URL_CATEGORY_2);
        System.out.println(matcher.matches());
    
        System.out.println("Matching categories");
        Matcher category = categoryPattern.matcher(URL_ITEM_1);
        System.out.println(category.matches());
        category = categoryPattern.matcher(URL_ITEM_2);
        System.out.println(category.matches());
        category = categoryPattern.matcher(URL_CATEGORY_1);
        System.out.println(category.matches());
        category = categoryPattern.matcher(URL_CATEGORY_2);
        System.out.println(category.matches());
    }
    }
    

    输出:

    Matching items
    true
    true
    false
    false
    Matching categories
    false
    false
    true
    true
    

    它将前两个第一个URLS验证为项目,最后两个作为类别。

    我希望它符合您的要求。随意适应JS。

答案 1 :(得分:1)

为了提高算法的复杂性,假设您使用的是Jsoup,则必须根据算法调整数据结构。

4)你对标签的位置是什么意思?标签的Xpath? 如果是,则为每个标记O(n)预先计算一次该值,并将该值存储在每个节点中。如果需要,您还可以将其存储在HashMap中以在O(1)中检索。

5)使用MultiMap按类名标记索引。你将节省大量的计算

6)没有Id,没有类名的索引类

所有这些预计算都可以在树的一次遍历中执行,因此O(n)。

通常,如果要减少计算,则必须在内存中存储更多数据。由于DOM页面是非常小的数据,因此在您的情况下这没有问题。