場景描述:
過往我們在抽取網頁標題的時候,都會直接抽取 之間的內容. 但實際情況是這樣,例如javaeye 的一篇文章 http://www.iteye.com/news/21643 , 的內容為 "10年軟件開發教會我最重要的10件事 - 非技術 - ITeye資訊", 但實際引用中我們期望的標題應該為 "10年軟件開發教會我最重要的10件事". 所以標題後面堆砌了很多不相關的關鍵字(應該是為了 seo 吧). 所以我們希望過濾掉這些關鍵字. 有下面的方法可以參考:
1. 查找 h1 等標簽.(分析sina news 一些網站之後, 覺得不可行,會有很多干擾)
2. 從全文去標題後,將 之間的內容切割(按 _ | -)為 a1,a2,a3,a4,然後從最長的詞組a3開始從全文查找. 如果查找成功,那麼開始向左邊迭代查詢 a2,a1,直到查詢失敗為止 。左側失敗後,再繼續向右迭代,同理. (這裡我采用的是這種方法)
Php代碼
<?php
/**
* @author pqcc <[email protected]>
* @date: 2011-06-18
* Description: 給定一個網頁內容,提取網頁的標題. 提取的標題不包括 seo 關鍵字.
* e.g: 一篇新聞標題的從<title>直接抽取結果為 "大學英語四六級本周六開考 909萬人參考_新浪教育_新浪網",
* 但我們希望的結果是:"大學英語四六級本周六開考 909萬人參考".
* 適用范圍: 文章最終頁標題的提取, 不包括專題頁等.
*/
class TitlePurify{
private $matches_preg = [-_s|—];
function getTitle($contents){/*{{{*/
$preg = "/<title[^>]*>([w| ||W]*?)</title>/i";
preg_match($preg, $contents, $matches);
if(count($matches)<=1){
return "標題抽取失敗";
}
$title = $matches[1];
return $this->trimTitle($title, $contents);
}/*}}}*/
function trimMeta($contents){/*{{{*/
// 首先去除 <title> 內容, <meta> 內容.
$preg = "/<title[^>]*>([w| ||W]*?)</title>/i";
$contents = preg_replace($preg, , $contents);
$preg = "/<meta[^>]*>/i";
$contents = preg_replace($preg, , $contents);
return $contents;
}/*}}}*/
// 獲取長度最長的 item 所處的index.
function getMaxIndex($titles){/*{{{*/
$maxItemIndex = 0;
$maxLength = 0;
$loop = 0;
foreach($titles as $item){
if(strlen($item)>$maxLength){
$maxLength = strlen($item);
$maxItemIndex = $loop;
}
$loop++;
}
return $maxItemIndex;
}/*}}}*/
function trim($title, $titles, $contents, $maxItemIndex){/*{{{*/
//@todo : 此處可優化contents
// 如果查找成功. result = tempTitle.
$tempTitle = $titles[$maxItemIndex];
$result = $tempTitle;
$count = count($titles);
// while 從當前index 向左進行迭代(直到到達第一個或者匹配失敗才中止).
$leftIndex = $maxItemIndex-1;
while(true && $leftIndex>=0){
// tempTitle+左一個.
preg_match("/({$this->matches_preg}+{$tempTitle})/i", $title, $matches);
if(count($matches)>1){
// temp 用於匹配失敗後,進行回滾.
$temp = $titles[$leftIndex] . $matches[1];
$tempTitle = $titles[$leftIndex] . $matches[1];
// 繼續拿著 tempTitle 去匹配.
preg_match("/$tempTitle/i", $contents, $matches);
// 如果查找失敗....
if(count($matches)<1){
$tempTitle = $temp;
break;
}else{
$result = $tempTitle;
}
}else{ // 正常情況下, 不會出現該情況.
break;
}
$leftIndex--;&