织梦采集侠获取文章标题原理,附上php源码

作者:enenba | 发表于:2012-08-02 17:28 | 分类:php采集

     我这几天看了下织梦采集侠的源码,发现有很多成熟的技术,比如这个采集网站文章的题目,源码一会再上,先做简单解释:


     首先,很多人会一直会认为这不是很简单,就是<title>标签中的内容嘛,不是很容易获取吗?其实不然,很多的title部分不一定放文章的题目,很多的网站还加入了关键字,而且一定加入网站名。


     如:“php采集网站的title_php采集_EnEnBa Blog”,对于一个采集者来说此文章只需要“php采集网站的title”就可以了,“_php采集_EnEnBa Blog”部分不是我们想要的。要过渡掉。


     还有就是可以从文章的标题标签中找出来,如h1 h2 h3 等标签,很多建站者注意了这些标签的权重,很容易也写出正则获取。但是也有例外,人家没有写<h1>这些标签呢,此方法不适用所有网站。

 

织梦采集侠就考虑了以上的两种情况并写出了很完美的解决方案。
1、首先获取页面下的所有<title>和<h……>标签
2、对比title 和 <h……>中的内容。如果一样的部分就返回<h……>中的内容
3、如果没有<h……>的内容,对title部分按分割符进行分割,常用的标题分隔有 “-”、“—”、“_”、“>”、“|” ,返回最长的字符串。

 

演示:http://enenba.com/tool/get_title/

上源码吧,从采集侠源码中提取的,注意编码为utf-8,

 

<?php
/**
 * 采集文章的题目
 * @param string  $html  需要采集的html源代码
 * @param int $maxlen    最大题目长度
 * @return   string
 */
function TT($html,$maxlen) {
	if (preg_match("/<title>(.*)<\/title>/isU", $html, $t)) {
		if (preg_match_all("/<h([1-3])(?:[^>]*)>(.*)<\/h\\1>/isU", $html, $ts)) {
			foreach($ts[2] as $vt) {
				if (strpos($t[1], $vt) !== false) return $vt;
			} 
		} 
		$t[1] = str_replace(array('-', '—', '_', '>'), '|', $t[1]);
		$splits = explode('|', $t[1]);
		$l = 0;
		foreach ($splits as $tp) {
			$len = strlen($tp);
			if ($l < $len) {
				$l = $len;
				$tt = $tp;
			} 
		} 
		$tt = trim(str_replace('"', '"', cn_substr(html2text($tt), $maxlen)));
		return $tt;
	} 
	return false;
} 
/**
 *  HTML转换为文本
 *
 * @param    string  $str 需要转换的字符串
 * @param    string  $r   如果$r=0直接返回内容,否则需要使用反斜线引用字符串
 * @return   string
 */
function html2text($str,$r=0) {
	$str = preg_replace("/<sty(.*)\\/style>|<scr(.*)\\/script>|<!--(.*)-->/isU", "", $str);
	$alltext = "";
	$start = 1;
	for($i = 0;$i < strlen($str);$i++) {
		if ($start == 0 && $str[$i] == ">") {
			$start = 1;
		} else if ($start == 1) {
			if ($str[$i] == "<") {
				$start = 0;
				$alltext .= " ";
			} else if (ord($str[$i]) > 31) {
				$alltext .= $str[$i];
			} 
		} 
	} 
	$alltext = str_replace(" ", " ", $alltext);
	$alltext = preg_replace("/&([^;&]*)(;|&)/", "", $alltext);
	$alltext = preg_replace("/[ ]+/s", " ", $alltext);
	if($r==0){
		return $alltext;
	}else {
		$r = SpHtml2Text(stripslashes($alltext));
		return addslashes($r);
	}
} 

/**
 * utf-8中文截取,单字节截取模式
 * 
 * @access public 
 * @param string $str 需要截取的字符串
 * @param int $slen 截取的长度
 * @param int $startdd 开始标记处
 * @return string 
 */

function cn_substr($str, $length, $start = 0) {
	if (strlen($str) < $start + 1) {
		return '';
	} 
	preg_match_all("/./su", $str, $ar);
	$str = '';
	$tstr = ''; 
	for($i = 0; isset($ar[0][$i]); $i++) {
		if (strlen($tstr) < $start) {
			$tstr .= $ar[0][$i];
		} else {
			if (strlen($str) < $length + strlen($ar[0][$i])) {
				$str .= $ar[0][$i];
			} else {
				break;
			} 
		} 
	} 
	return $str;
} 
?>

测试使用:

<?php
//以下为测试内容
$url = 'http://enenba.com/?post=85';
$httptype = function_exists('curl_init');
if (!$httptype) {
	$html = file_get_contents($url);
} else {
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_HEADER, 1);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$html = curl_exec($ch);
	if ($html === false) echo "cURL Error: " . curl_error($ch);
}
$r = TT($html,120);
//输出
if($r){
echo '此文章的题目为:《'.$r.'》';
}else{
echo '无信息';
}
?>

 

 

 

 

 

 

phpcms采集侠有精简版:

 

function cjx_gettt($str){
	if(preg_match("/<title>(.*)<\/title>/isU", $str, $t)){
        if(preg_match_all("/<h([1-3])>(.*)<\/h\\1>/isU", $str, $ts))
            foreach($ts[2] as $vt)
                if(strpos($t[1],$vt)!==false) return $vt;
        $t[1] = str_replace(array('-','—','|'),'_',$t[1]);
		$splits = explode('_', $t[1]);
		$l = 0;
		foreach ($splits as $tp){
			$len = strlen($tp);
			if ($l < $len){$l = $len;$tt = $tp;}
		}
        $tt = trim(htmlspecialchars($tt));
        if(strlen($tt)>20) return $tt;
	}
	return false;
}

 本站原创内容,转载保留出处:http://enenba.com/?post=228

end

上一篇: 【转】PHP Simple HTML DOM解析器使用入门   |   下一篇:【转】解决虚拟空间网站301重定向的两种方法» 标签: php源码 采集 织梦采集侠 文章标题

评论:

2012-09-16 10:44

我当年用DEDECMS做色情网站的时候天天采集,现在已经很熟练,还会MAXCMS采集快播了

2012-08-06 19:05

好久没来了