1. 程式人生 > >python使用BeautifulSoup的prettify功能來處理HTML文件,之後使用Levenshtein編輯距離計算文件間的相似度

python使用BeautifulSoup的prettify功能來處理HTML文件,之後使用Levenshtein編輯距離計算文件間的相似度

    字串的處理可謂是一個老生常談的話題了,處理的方法也是有很多的積累的,利用字串的匹配來計算文件整體之間的相似度是一個慣用的方法,但裡面還有很多具體的細節需要注意,今天在使用Levenshtein距離的時候遇到了一個問題,不太知道該如何衡量了,這裡先說一下做的事情:

    首先使用BeautifulSoup來解析html文件,去除除了html文件非標籤節點之外的內容,之後使用prettify函式格式化輸出,在得到兩個文件的DOM_TAG樹之後就是用Levenshtein距離來計算文件之間的相似度,當然這裡參與直接運算的就是每一個標籤節點的字串。這個事的目的就是想簡單的測試一下Levenshtein距離的時間複雜度以及用於後續計算的話是否可行。

    選取的比對物件是百度和京東的html,下面是格式化輸出的結果:

<html>
 <head>
  <meta/>
  <meta/>
  <meta/>
  <meta/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <title>
  </title>
  <style>
  </style>
  <style>
  </style>
  <style>
  </style>
  <style>
  </style>
  <style>
  </style>
  <style>
  </style>
  <script>
  </script>
  <noscript>
   <meta/>
  </noscript>
  <script>
  </script>
 </head>
 <body>
  <script>
  </script>
  <div>
   <script>
   </script>
   <div>
    <div>
     <div>
      <div>
       <div>
        <img/>
       </div>
       <a>
        <img/>
       </a>
       <form>
        <input/>
        <input/>
        <input/>
        <input/>
        <input/>
        <input/>
        <input/>
        <span>
         <input/>
        </span>
        <span>
         <input/>
        </span>
        <span>
         <span>
          <div>
           <span>
           </span>
          </div>
          <ul>
           <li>
            <a>
            </a>
           </li>
           <li>
            <a>
            </a>
           </li>
           <li>
           </li>
           <li>
            <a>
            </a>
           </li>
          </ul>
         </span>
        </span>
        <input/>
        <input/>
        <input/>
        <input/>
        <input/>
       </form>
       <div>
       </div>
      </div>
     </div>
     <div>
      <a>
      </a>
      <a>
       <i>
       </i>
      </a>
      <a>
      </a>
     </div>
     <div>
      <a>
      </a>
      <a>
      </a>
      <a>
      </a>
      <a>
      </a>
      <a>
      </a>
      <a>
      </a>
      <a>
      </a>
      <a>
      </a>
      <a>
      </a>
     </div>
    </div>
   </div>
   <div>
    <b>
    </b>
    <a>
    </a>
    <a>
    </a>
    <a>
    </a>
    <a>
    </a>
    <a>
    </a>
    <a>
    </a>
    <a>
    </a>
    <a>
    </a>
    <a>
    </a>
   </div>
   <div>
    <div>
     <div>
      <div>
      </div>
      <div>
       <p>
        <b>
        </b>
       </p>
      </div>
     </div>
    </div>
   </div>
   <div>
    <div>
     <div>
      <p>
       <a>
       </a>
       <a>
       </a>
       <a>
       </a>
       <a>
       </a>
      </p>
      <p>
       <a>
       </a>
       <a>
       </a>
       <i>
       </i>
       <a>
       </a>
       <i>
       </i>
      </p>
     </div>
    </div>
   </div>
   <div>
   </div>
  </div>
  <div>
  </div>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
 </body>
</html>
------------------------------------------------jd------------------------------------------------------
<html>
 <head>
  <meta/>
  <title>
  </title>
  <meta/>
  <meta/>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <link/>
  <meta/>
  <meta/>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <style>
  </style>
  <script>
  </script>
  <script>
  </script>
 </head>
 <body>
  <script>
  </script>
  <div>
   <div>
    <ul>
     <li>
     </li>
    </ul>
    <ul>
     <li>
      <a>
      </a>
      <a>
      </a>
     </li>
     <li>
     </li>
     <li>
      <div>
       <a>
       </a>
      </div>
     </li>
     <li>
     </li>
     <li>
      <div>
       <a>
       </a>
       <i>
       </i>
       <i>
        <s>
        </s>
       </i>
      </div>
      <div>
      </div>
     </li>
     <li>
     </li>
     <li>
      <div>
       <a>
       </a>
      </div>
     </li>
     <li>
     </li>
     <li>
      <div>
       <a>
       </a>
      </div>
     </li>
     <li>
     </li>
     <li>
      <div>
       <i>
       </i>
       <i>
        <s>
        </s>
       </i>
      </div>
      <div>
      </div>
     </li>
     <li>
     </li>
     <li>
      <div>
       <i>
       </i>
       <i>
        <s>
        </s>
       </i>
      </div>
      <div>
      </div>
     </li>
     <li>
     </li>
     <li>
      <div>
      </div>
      <div>
       <div>
       </div>
      </div>
      <div>
      </div>
     </li>
    </ul>
   </div>
  </div>
  <div>
   <div>
    <div>
     <h1>
      <a>
      </a>
     </h1>
     <h2>
     </h2>
     <div>
     </div>
    </div>
    <div>
     <div>
      <div>
       <a>
       </a>
      </div>
      <ul>
      </ul>
      <div>
       <input/>
       <button>
        <i>
        </i>
       </button>
      </div>
     </div>
    </div>
    <div>
     <div>
      <i>
      </i>
      <i>
      </i>
      <i>
      </i>
      <a>
      </a>
     </div>
     <div>
      <div>
      </div>
      <div>
       <span>
       </span>
      </div>
     </div>
    </div>
    <div>
    </div>
    <div>
     <ul>
      <li>
       <a>
       </a>
      </li>
      <li>
       <a>
       </a>
      </li>
      <li>
       <a>
       </a>
      </li>
      <li>
       <a>
       </a>
      </li>
     </ul>
     <div>
     </div>
     <ul>
      <li>
       <a>
       </a>
      </li>
      <li>
       <a>
       </a>
      </li>
      <li>
       <a>
        <img/>
       </a>
      </li>
      <li>
       <a>
       </a>
      </li>
     </ul>
     <div>
     </div>
     <ul>
      <li>
       <a>
       </a>
      </li>
     </ul>
    </div>
    <div>
    </div>
   </div>
  </div>
  <div>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
   <a>
   </a>
  </div>
  <div>
   <div>
    <div>
     <div>
      <ul>
       <li>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
       <li>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
        <span>
        </span>
        <a>
        </a>
       </li>
      </ul>
      <div>
      </div>
     </div>
    </div>
    <div>
     <div>
      <div>
      </div>
      <div>
      </div>
     </div>
    </div>
    <div>
     <div>
     </div>
     <div>
      <div>
       <div>
        <a>
        </a>
        <a>
        </a>
        <div>
        </div>
        <a>
        </a>
       </div>
       <div>
        <div>
         <ul>
          <li>
           <a>
           </a>
          </li>
          <li>
           <a>
           </a>
          </li>
          <li>
           <a>
           </a>
          </li>
          <li>
           <a>
           </a>
          </li>
         </ul>
        </div>
        <div>
         <ul>
          <li>
           <a>
           </a>
          </li>
          <li>
           <a>
           </a>
          </li>
          <li>
           <a>
           </a>
          </li>
          <li>
           <a>
           </a>
          </li>
         </ul>
        </div>
       </div>
      </div>
     </div>
     <div>
      <div>
       <ul>
        <li>
         <a>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
        <li>
         <a>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
        <li>
         <a>
          <span>
           <i>
           </i>
           <i>
           </i>
          </span>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
        <li>
         <a>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
        <li>
         <a>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
        <li>
         <a>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
        <li>
         <a>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
        <li>
         <a>
          <span>
           <i>
           </i>
           <i>
           </i>
          </span>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
        <li>
         <a>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
        <li>
         <a>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
        <li>
         <a>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
        <li>
         <a>
          <i>
          </i>
          <span>
          </span>
         </a>
        </li>
       </ul>
      </div>
      <div>
       <div>
       </div>
       <div>
       </div>
       <div>
       </div>
       <div>
       </div>
       <a>
       </a>
      </div>
     </div>
    </div>
   </div>
   <div>
   </div>
  </div>
  <style>
  </style>
  <script>
  </script>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <div>
  </div>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
  <script>
  </script>
 </body>
</html>

    一共採用了兩種計算方法:

1.使用文件1中的每個字串和文件2中的每一個字串計算編輯距離,之後的結果除以:m*n,其中,m和n分別為文件1,2 的長度

2.使用文件長度較小的文件作為基準,將其中每個字串另一個文件中的字串1對n比對計算,只選取每一輪比對計算中編輯距離的最小值累加,結果除以兩個文件長度的平均值

得到的結果如下:

**********************************calculate_distance_simple******************************************
4.59702930817
0.594041983813
***************************************calculate_distance_complex**************************************
0.512249443207
0.331642362975
    其中,calculate_distance_simple是第一種方法的結果,calculate_distance_complex是第二種方法的結果

    現在的疑惑就是:如果我單純的只是用這樣的編輯距離來計算總體的距離而不加入類似:樹的深度、枝葉長度等輔助資訊的化很難拉開區分度,百度和京東本身就是很不相似的頁面,但是這樣的計算得到的相似度比率卻是很高的,暫時還沒想到該如何找到一個更好的衡量相似度的策略,當然這也只是一個很簡單的嘗試沒有太大的意義,只是想拿兩個很不相似的頁面來試驗一下,期望得到的比率值應該是很低的才對,但是結果卻並不是這樣的。

    此外,方法中使用的Levenshtein方法是一個python實現的庫,python-Levenshtein,網上可以收到,下載之後,直接可以使用:python setup.py install安裝,中間囊括了之中常見的距離計算方法,如:編輯距離、漢明距離等等,如果有需要可以下載使用,歡迎指點迷津!