基于视觉的网页结构相似性计算

来源:互联网 发布:php最新面试题 编辑:程序博客网 时间:2024/06/15 17:29

      由于工作学习的安排,一直参与项目课题的工作,期间在计算两个页面之间相似度的时候,寻求到了一个新的思路,于是努力实现了一下,这里简单说一下自己在接到这个问题的时候的思路吧:网页的相似度,分类,聚类之类的工作很多大牛都做了很多的研究,基于文本、内容、图像各个方面的都有,效果也还是可以的,这次出发点是网页的视觉信息但是在真的动手去做的时候却发现视觉信息包含的计算量太过于庞大了,而且需要很多的预处理,没有一定的先验知识是无法做好的,之前有学长做过这方面的东西,我呢这次也是“站在巨人的肩膀上”出发的哈,网页的源码html通过浏览器提供的渲染接口展现给我们的是DOM树,也就是文档对象模型,之所以很多页面会出现视觉上相似的那是检测算法却判定结果相似性较低甚至不相似的原因是,html中包含一定的js,之中的内容是不被显示的,而且基于大量的数据分析发现html中存在很多的伪装方式,他们通过篡改页面的内容设置属性隐藏、iframe内嵌等等的伪装方式来逃避一系列针对这个伪装的检测方法,应对这些伪装最好的办法就是渲染html得到页面真实的DOM树结构,将那些被伪装或者被隐藏的信息都显示出来,直接操作html效果不好,现在换成是操作DOM树,这样一来,得到的分析和处理结果更接近于真实,这里就是这样的思路。

    首先通过对html的渲染得到了页面的DOM树形式,然后利用得到的DOM的视觉块信息来进行下一阶段的处理,对页面中出现的每一个视觉块均从三个方面进行切割划分考虑,这里使用的是差分切割,对与不同级的信息赋予不同的表示序列最终使用得到的表示序列作为页面的身份信息来用作后续步骤中的检索查询与匹配计算。这里不再累赘,下面是详细的处理程序。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division

import os
import math
import time
from whoosh.index import create_in
from whoosh.fields import *
import whoosh.index as index
from whoosh.qparser import QueryParser


def CutSquence(file_block_list, web_height, web_width):
    '''
    读取页面信息,从位置中心、面积、高宽比三个方面对其进行分割最终得到一个26位长度的结构特征序列
    '''
    #print 'web_height is :' , web_height
    #print 'web_width is :' , web_width
    #print  'file_block_list is ',file_block_list
    structure = []
    structure_dict = {}
    for i in range(len(file_block_list)):
        center_x = int(file_block_list[i][3]) * 0.5
        center_y = int(file_block_list[i][2]) * 0.5
        s_x = center_x + int(file_block_list[i][1])
        s_y = center_y + int(file_block_list[i][0])
        angle1 = math.atan(s_x/s_y)
        angle2 = math.atan(s_y/(int(web_width)-s_x))
        angle3 = math.atan((int(web_width)-s_x)/(int(web_height)-s_y))
        angle4 = math.atan((int(web_height)-s_y)/s_x)
        string = locate_binary((angle1,angle2,angle3,angle4))
        area1 = int(file_block_list[i][2]) * int(file_block_list[i][3])
        area = area_binary(area1)
        hw_rate1 = int(file_block_list[i][2])/int(file_block_list[i][3])
        hw_rate = hw_rate_binary(hw_rate1)
        long = str(string + area + hw_rate)
        #print  'string is ', string
        #print 'area is ', area
        #print 'hr_rate is' , hw_rate
        structure.append(long)
    return structure
    #print 'structure_squence is :', structure


def locate_binary(angle):
    '''
    对角度进行分割,输入时一个四元组,如(0.132,0.23,0.45,0.671)
    '''
    locate = ''
    locate_dict = {1:'0000',2:'0001',3:'0010',4:'0011',5:'0100',6:'0101',7:'0110',8:'0111',9:'1000',10:'1001',11:'1010',12:'1011',
                    13:'1100',14:'1101',15:'1110',16:'1111'}
    for item in angle:
        result = item/0.0982
        value = int(math.ceil(result))
        if value in locate_dict:
            locate = locate + locate_dict[value]
        elif value >= 16:
            locate = locate + '1111'
    return locate


def area_binary(area):
    '''
    对面积进行差分切割,输入时一个面积值,如670000
    '''
    result = ''
    area_binary_dict = ((5000,'00000'),(10000,'00001'),(30000,'00010'),(50000,'00011'),(70000,'00100'),(90000,'00101'),(110000,'00110'),
                        (130000,'00111'),(150000,'01000'),(170000,'01001'),(190000,'01010'),(210000,'01011'),(230000,'01100'),(250000,'01101'),
                        (270000,'01110'),(290000,'01111'),(310000,'10000'),(330000,'10001'),(350000,'10010'),
                        (370000,'10011'),(390000,'10100'),(410000,'10101'),(430000,'10110'),(450000,'10111'),
                        (470000,'11000'),(490000,'11001'),(500000,'11010'),(750000,'11011'),
                        (1000000,'11100'),(2000000,'11101'),(3000000,'11110'),(4000000,'11111'))
    if area > 4000000:
        result = result + '11111'
    else:
        for i in range(len(area_binary_dict)):
            if area <= area_binary_dict[i][0]:
                result = result + area_binary_dict[i][1]
                break
    return result


def hw_rate_binary(hw_rate):
    '''
    对高宽比进行差分切割,输入时一个四高宽比率,如0.12
    '''
    result = ''
    hw_rate_binary_dict = ((0.05,'00000'),(0.1,'00001'),(0.15,'00010'),(0.2,'00011'),(0.25,'00100'),(0.3,'00101'),
                            (0.325,'00110'), (0.35,'00111'),(0.375,'01000'), (0.4,'01001'),(0.45,'01010'),
                            (0.5,'01011'),(0.55,'01100'),(0.6,'01101'),(0.65,'01110'),(0.7,'01111'),
                            (0.725,'10000'),(0.75,'10001'),(0.775,'10010'),(0.8,'10011'),(0.825,'10100'),
                            (0.85,'10101'),(0.875,'10110'),(0.9,'10111'),(0.925,'11000'),(0.95,'11001'),
                            (1,'11010'),(1.25,'11011'),(1.5,'11100'),(1.75,'11101'),
                             (3,'11110'),(4,'11111'))
    if hw_rate >= 4:
        result = result + '11111'
    else:
        for i in range(len(hw_rate_binary_dict)):
            if hw_rate <= hw_rate_binary_dict[i][0]:
                result = result + hw_rate_binary_dict[i][1]
                break
    return result          


if __name__ == '__main__':
    CutSquence(file_path = "1.txt")

0 0
原创粉丝点击