???紵 发表于 2017-4-10 06:08:39

php无需设置规则,抓取网页主要内容的实现

  在网上经常看到一些网页采集方案,,但总绕不过采集规则的设置,每抓取一种类型的网页需要设置一种规则。。用这些规则进行替换,正则,踢除等操作,,然后取出页面的内容。。

有没有一种好的方法,不用我们为每一种类型的网页书写规则呢??

下面就来讨论这个问题::

比如我们抓取新浪新闻的内容,我们看到每个新闻内容那一块,代码基本是整个网页里面字符数最多的,如果我们把这一块代码取出来,不就达到我们的目的了吗?

我们知道html其实是xml的一种,我们把新浪某个新闻的显示代码当作xml来处理,,

我们找出这个xml页面里面所有的父节点,以及父节点里面包含的子节点,,将他们写入一个数组,,

然后以这些节点字符串的长度,由大到小,对这些节点进行排序,,,理论上,,排序后的数组,第一个节点即是我们需要的内容。。。

另,一个页面中可能有许多js广告代码或者css代码,我们可以将他们先清除,,以减少误差。。

还有一个问题,因为我们是取出一个页面所有的节点,,一个大的页面,,节点太多了,,很耗资源,,有时可能造成机器崩溃,,那么该怎么办呢??

我们发现一般新闻内容节点大部分是<div>,<td>,那么我们可以只取这两种节点即可,,可以节省许多资源,,具体取那种节点也可以自己设置。。。

另一种节省资源的方案是这样的,,比如我发现新闻内容节点里面必须包含“新浪”这两个字,,那么我们可以把不包含这两个字的节点去掉。。相反的道理,如果新闻内容节点不包含“新浪”这两个字,我们也可以剔除包含这两个字的节点。。当然这种剔除多余节点的规则也很多。。

最后我们也可以用“similar_text”这个函数来去除一些节点,减少干扰,具体做法,请读者自己体会:

similar_text() 函数计算两个字符串的匹配字符的数目。

该函数也可以计算两个字符串的相似度(以百分比计)。

下面我给出我的一个简单方案:

需要用到"simple_html_dom",具体请打开 http://simplehtmldom.sourceforge.net/

下面是代码:可以输入网址如: http://news.sina.com.cn/c/2010-10-21/085321321471.shtml试试
<?php
//自动得到文章
include('simplehtmldom/simple_html_dom.php');
function requests($str) {
    return isset($_REQUEST[$str]) ? $_REQUEST[$str]:"";
}
//include('../include/config.php');
$similar = 40; //相似度
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
</head>
<body>
<div style="width:760px; margin:0 auto;">

<div>
<form name="sad" method="post" action="">

<input type="text" name="str" value="" size=100 ><br>
<input type="submit" name="sub" value="提交">

</form>
</div>
<div style="width:600px;">
<?
$str = requests("str");
if($str != ""){
$str = trim($str);
$str = file_get_contents($str);
$str = strtolower($str);
//去js css
$str = preg_replace("'<script[^>]*?>.*?</script>'si", "", $str);
$str = preg_replace("'<style[^>]*?>.*?</style>'si", "", $str);

$html = str_get_html($str);
$tagarr = array('div', 'td','li');
$rs = array();
foreach($tagarr as $tag){
    $tdo = $html->find($tag);
    $tds = array();
    foreach($tdo as $tv){
        $tds[] = $tv->innertext;
    }
    foreach($tds as $v){
        $v = strip_tags($v);
        $len = strlen($v);
        $rs[$len] = $v;
    }

}

ksort($rs);
$tarr =array_reverse($rs);
//fdebug($tarr);
$i = 0;
$len = count($tarr);
$tarr2 = $tarr;
for($i;$i <$len; $i++ ){
       $j = $i + 1 ;
    for($j ; $j < $len ; $j++){
        $intv = similar_text($tarr[$i], $tarr[$j]);
        $ra = number_format(($intv / strlen($tarr[$i])) * 100,2);
        if($ra > $similar){
            unset($tarr2[$i]);continue ;
        }
     // echo $ra ."<br>";
    }
   // echo $i . "=======================<br>";
}
unset($tarr);
//sort($tarr2);
$tarr =array_reverse($tarr2);
//fdebug($tarr);
$rv = "";
if(count($tarr) > 0){
$rv = $tarr;
$rv = str_replace(' ', '' , $rv);
$rv = str_replace('<br />', '' , $rv);
$rv = str_replace("\n", '' , $rv);
$rv = str_replace("\r", '' , $rv);
}
echo $rv;
}
?>
</div>
</div>
</body>
</html>
  首发地址 http://www.yichao123.com/a/v.php?id=500
页: [1]
查看完整版本: php无需设置规则,抓取网页主要内容的实现