首页编程PHP典型模块内容自动采集器模块文章详细

内容自动采集器程序实现

原创 2023-10-03 22:56:04 140

采集器模块包含3个部分,即爬虫程序、采集规则管理程序、采集内容管理程序,这些功能模块共同完成采集内容的抓取功能。本节将会以前面介绍的技术原理为基础,详细地介绍这几个组成部分的逻辑管理,以及具体的编码过程,其中涉及的知识点也会逐一详细讲解。

1.采集规则管理程序

采集规则管理程序的核心是基于正则表达式的内容管理程序。了解如何使用正则表达式获得指定的内容信息,是采集规则管理程序的重点。

正则表达式的应用范围非常广泛,涉及的内容也十分庞杂,读者如果感兴趣可以自己对照手册学习,这里不作详细阐述。这里主要介绍正则表达式在内容采集方面的应用。采集器的主要工作是应用正则表达式对页面代码做匹配,进而获得相应的内容。这也是正则表达式在Web方面的主要应用。下面的例子是使用PHP正则表达式提取超链接及其标题,代码如下:

$str = '<a id="top8" href="http://list.mp3.baidu.com/song/A.html?top8" class="p14" target="_top">歌曲列表</a>
<br>
<a target="_blank" id="bp" href="http://list.mp3.baidu.com/list/bangping.html"class="p14">中文金曲榜</a>
<br>
<td nowrap="nowrap">>#8226;>nbsp;<a id="top19" href="qingyinyue.html?top19" class="p14" target="_top">轻音乐</a></td>';
$pat = '/<a (.*?) href="(.*?)"(.*?)>(.*?)<\/a>/i';
preg_match_all($pat, $str,$m);
echo "<pre>";
print_r($m);
echo "</pre>";

执行上面一段代码,输出结果如下:

Array
(
    [0] => Array
        (
            [0] => <a id="top8" href="http://list.mp3.baidu.com/song/A.html?top8" class="p14" target="_top">歌曲列表</a>    
            [1] => <a target="_blank" id="bp" href="http://list.mp3.baidu.com/list/bangping.html"class="p14">中文金曲榜</a>    
            [2] => <a id="top19" href="qingyinyue.html?top19" class="p14" target="_top">轻音乐</a>    
        )

    [1] => Array
        (
            [0] => id="top8"
            [1] => target="_blank" id="bp"
            [2] => id="top19"
        )

    [2] => Array
        (
            [0] => http://list.mp3.baidu.com/song/A.html?top8
            [1] => http://list.mp3.baidu.com/list/bangping.html
            [2] => qingyinyue.html?top19
        )

    [3] => Array
        (
            [0] =>  class="p14" target="_top"
            [1] => class="p14"
            [2] =>  class="p14" target="_top"
        )

    [4] => Array
        (
            [0] => 歌曲列表
            [1] => 中文金曲榜
            [2] => 轻音乐
        )

)

【代码解读】

通过上述代码可以了解到,通常的PHP正则表达式提取超链接获得内容的基本步骤。根据前面的需求分析可以知道,采集器模块涉及两个部分规则定制,即页面网址提取规则和页面内容提取规则。本章设定的抓取页面(http://auto.sina.com.cn/news/t/)是一个网站的汽车频道的列表页面。

URL列表页面的链接样式如下:

<1i><ahref="/news/2010-05-21/1705605024 4.shtml"title=”自主的胜利?target="_blank"class="f1">自主的胜利?</a ></li>

通过观察链接的特征,书写如下正则表达式来获得匹配信息。

$list match /<1i> <a href="(\/news\/.+?\.shtml)" title=".+?”
target="_blank"class="f1">/';

获得内容页面的正则表达式依据和上面的方法一样,通过观察内容页面模块的部分HTML代码,可以得到正则匹配规则如下:

<!--publish_helper(.+?)-->(.+?)<!--publish_helper_end-->/is

现在打开manage.php文件添加保存规则部分的代码,下面的程序将上面的功能做了整合,这样就可以完成一个完整的功能,代码如下:

<?php
    $con = mysqli_connect('localhost', 'root', 'root') or die('Could not connect: ' . mysqli_error());
    @mysqli_query("SET NAMES 'utf-8'",$con);//设定字符集编码
    //echo 'Connected successfully';
    $db=mysqli_select_db($con,'get_content');
    if (!$db){
        die ("Can\'t use download : " . mysqli_error());
    }else{
        $sql = "SELECT * FROM `spiders` LIMIT 0 , 30  ;";
        $result = mysqli_query($con,$sql);
        $row=mysqli_fetch_array($result);
        if($_POST['flag']==1){
            // 更新定义规则
            $sql1 = "UPDATE `get_content`.`spiders` SET `ListPreg` = '".$_POST['ListPreg']."',`ContentPreg` = '".$_POST['ContentPreg']."',`EnterUrl` = '".$_POST['EnterUrl']."' WHERE `spiders`.`ID` =4 LIMIT 1 ;";
            $result1 = mysqli_query($con,$sql1);
            mysql_free_result($result1);
            // 关闭连接
            mysqli_close($db);
            header("location:manage.php");
        }
    }
?>
<table align=center cellspacing=0 cellpadding=0>
    <form method="post" action="manage.php">
        <input type="hidden" name="flag" value="1"> 
        <tr class=head>
            <td colspan="2">采集器管理</td>
        </tr>
        <tr class=line>
            <td width="11%">采集器描述</td>
            <td width="89%"><input name="Title" type="text" class="input" id="Title" size="40" value="" /></td>
        </tr>
        <tr class=line>
            <td width="11%">所属栏目</td>
            <td width="89%">
                <select name="Category">
                    <option value="1">汽车频道</option>
                </select>
            </td>
        </tr>
        <tr class=line>
            <td valign="top">列表页面地址</td>
            <td><input name="EnterUrl" type="text" class="input" value="<?php echo $row['EnterUrl']?>" size="60" /></td>
        </tr>
        <tr class=line>
            <td valign="top">列表页匹配描述</td>
            <td><textarea name="ListPreg" cols="80" rows="4" class="input"><?php echo $row['ListPreg']?></textarea></td>
        </tr>
        <tr class=line>
            <td valign="top">内容页匹配描述</td>
            <td><textarea name="ContentPreg" cols="80" rows="4" class="input"><?php echo $row['ContentPreg']?></textarea></td>
        </tr>
        <tr class=line>
            <td colspan="2" align="center">
                <input name="Submit" type="submit" class="btn" value="提交" />
                <input name="Submit" type="button" class="btn" value="返回" onclick="history.go(-1);">
            </td>
        </tr>
    </form>
</table>

【代码解读】

梳理以上代码的执行流程,步骤如下:

(1)在第一次运行manage.php程序时,从数据库中提取spiders表中的规则信息。

(2)以数组的形式,传送值给表单中对应的标签显示出来。

(3)当对表单中的信息做修改之后,再将表单中的信息以POST的方式发送给PHP程序处理,然后更新数据库中的内容。

注意:设置一个隐藏的<input type="hidden"name="flag" value="1">标签,其中标签的值表示程序执行流程的编号,通过判断flag标签的值来实现流程控制,请读者在预读代码的时候注意。

运行manage.php程序,预览效果如图1.3所示,从图中可以看到数据库的规则信息被传到表单中了。

image.png

图1.3 采集器规则修改

2. 爬虫程序

爬虫程序即信息采集程序(spiders.php),通过前几节介绍,读者应该已经对爬虫程序的实现原理有了直观的了解,同时也有了一个爬虫程序的基本模型。下面继续完善这个框架程序的业务流程(如添加信息入库等部分内容)。在完善该程序之前,需要给采集器一个启动的入口,这里设定当采集器规则定制完成后就可以开始采集信息了。打开manage.php这个文件找到如下代码:

<td colspan="2"align="center">
    <input name="Submit"type="submit" class="btn"value="提交”/>
    <input name="Submit" type="button"class="btn"value="返回”onclick="history.go(-1);"/>
</td>

将上述代码修改为:

<td colspan="2" align="center">
    <input name="Submit"type="submit" class="btn"value="规则提交”/>
    <input name="Submit"type="button" class="btn"value="开始采集”onclick="1oadS1()">
</td>

【代码解读】

可以看到,当单击“开始采集”按钮后将触发loadS1()这个JavaScript函数,它的功能就是运营采集程序spiders.php

下面介绍具体的函数。添加loadS1()manage.php文件中,loadS1()的代码如下:

<script>
function loadS1()
{
 window.open ('spiders.php?cid=1') 
}
</script>

    其中,cid=1的意思是加载栏目id为1的规则开始采集。下面来看具体的spiders.php程序的代码实现:

//============================
//  文件: spiders.php
//  版本: 0.0.1
//  作者: 
//  更新: 
//  说明: 网页采集器程序
//============================
//获得栏目id
$Category=$_GET['cid'];
if($Category){
        $con = mysqli_connect('localhost', 'root', 'root') or die('Could not connect: ' . mysqli_error());
        @mysqli_query("SET NAMES 'utf-8'",$con);//设定字符集编码
        //echo 'Connected successfully';
        $db=mysqli_select_db($con,'get_content');
        if (!$db){
        die ("Can\'t use download : " . mysqli_error());
        }else{
          // 获得提取规则数组
        $sql = "SELECT * FROM `spiders` WHERE `Category`='".$Category."' ";
        $result = mysqli_query($con,$sql);
                $row=mysqli_fetch_row($result);
                if (!$result) {
        // 释放结果集
                mysqli_free_result($result);
            }   
        }
    }else{
        exit("出错了:(");
}
//待获取页面的地址
$list_url = $row[5];
//获取链接列表
$list_content = file_get_contents($list_url);
//$list_content = '';//**当采集列表页面无法准确锁定列表信息时候,将列表代码复制进来进行正则匹配
//观察链接特征:<li> <a href="/news/2010-05-21/1705605024_4.shtml" title="自主的胜利?" target="_blank" class="fl">自主的胜利?</a><i>/news/hy/2022-08-29/detail-imiziraw0165220.shtml
//获取列表正则规则
$list_match = $row[2];
//获得文章内容正则规则
$content_match=$row[3];
//$content_match='/<div class="content">(.*?)<\/div>/siU';//手动赋值内容正则规则
preg_match_all($list_match,$list_content,$list_data);
$i=0;
//获取到了一个链接列表
foreach($list_data[1] as $detail_url){
    //处理一下,如果已经抓取过了,就跳过去
    $detail_content = file_get_contents("http://gd.61w.cn/" . $detail_url);
    if($detail_content){
        //echo ($i++);
        //获取标题
        preg_match('/<h1>(.+?)<\/h1>/U',$detail_content,$title_data);
        $title=$title_data[1];
        //die($title);
        //获取内容,需要根据不同特点写正则
        preg_match_all('/<div class="content">(.*?)<\/div><\/div><!-- 中国古典著作大全网顶部书籍内容页底部 -->/siU',$detail_content,$body_data);
        $body=$body_data[0][0];
        echo "页面标题为:《".$title."》".'<br/>';
        echo "主体内容为:".$body.'<br/>';    
        //die($body_data[0][0]);
        $body = $body_data[0][0];
        $date = date('Y-m-d H:i:s', time());
        //$sql = "INSERT INTO 'get_content'.'articles'(`ID`, `Title`, `Click`, `Content`, `Date`, `Category`) VALUES (NULL,'".$title."','0','".$body."','".$datenow."','1');";
        $sql = "INSERT INTO `articles` VALUES (NULL,'".$title."','0','".$body."','".$date."','1');";
        $result =mysqli_query($con,$sql);
    }
    if($result){
        //mysqli_free_result($result);
        echo "页面标题为:《".$title."》数据采集成功!".'<br/>';
    }else{
        echo "页面标题为:《".$title."》数据采集失败!".'<br/>';
    }
}
    // 关闭连接
    mysqli_close($con);

【代码解读】

本章的爬虫程序的执行流程步骤如下:

(1)根据栏目id从数据库中读取对应的规则信息;

(2)通过file_get_contents()函数获得目标页面的内容;

(3)通过preg_match_all()函数获取链接列表,然后循环遍历该列表将所需的信息过滤后归档,存入数据的articles表中。

3. 获得需采集内容列表

前面介绍的爬虫程序,通过预先设置的规则将数据从目标站点下载到数据库中。现在需要写一个脚本程序将数据库中的内容以列表的形式展示出来,同时还要提供“修改”链接用来编辑、调整内容。采集内容列表程序的代码如下:

<?php
$con = mysqli_connect('localhost', 'root', 'root') or die('Could not connect: ' . mysqli_error());
    @mysqli_query("SET NAMES 'utf-8'",$con);//设定字符集编码
    $db=mysqli_select_db($con,'get_content');
    if (!$db){
      die ("Can\'t use download : " . mysqli_error());
    }else{
      // 获得文件详细信息
      $sql = "SELECT * FROM `articles` LIMIT 0,10 ";
      $result = mysqli_query($con,$sql);
      $num_rows = mysqli_num_rows($result);
      //$rows=mysql_fetch_array($result);
      //var_dump ($rows);
    }

?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>采集内容列表</title>
    <link href="admin.css" rel="stylesheet" type="text/css" />
</head>
<body>
<table align=center cellspacing=0 cellpadding=0>
    <tr class=head>
        <td colspan="4">栏目名称</td>
    </tr>
    <tr class=line>
        <td><strong>日期</strong></td>
        <td width="913"><strong>标题</strong></td>
        <td><strong>修改</strong></td>
       
    </tr>
        <?php
        for($i=0;$i<$num_rows;$i++){
        ?>
    <tr class=line>
        <td width="135">
        <?php
        $row=mysqli_fetch_array($result);
        echo $row['Date'];
        ?>
        </td>
        <td> <?php
        echo $row['Title'];
        ?></td>
        <td width="83"><a href="articles_save.php?aid=<?php echo $row['ID'] ;?>" target="_top">修改</a></td>
    </tr>
        <?php
        }
        ?>
    <tr class=line>
        <td colspan="4" align="center">&nbsp;</td>
    </tr>
</table>
</body>
</html>

将上述代码保存为articles.php文件。上述代码并不复杂,核心内容是将数据库中articles表中的内容取出,以列表形式输出到浏览器中。在浏览器中运行articles.php文件的效果如图8.4所示。

image.png

图8.4 文章列表

4. 内容编辑器

内容编辑器被广泛地应用在各种信息管理后台,它的作用是在线查看和编辑HTML代码和脚本程序。在本章中使用内容编辑器(FCKeditor)对文章内容进行预览和编辑。

FCKeditor是一个专门使用在网页上的文字编辑器,属于开放源代码的所见即所得形式,它是轻量级、不需要复杂安装过程的文字编辑器。下面来了解FCKeditor在PHP中的配置方法及使用。

1.下载及解压

从下面的地址下载新版本 FCKeditor:

http://www.fckeditor.net/download

将下载后的文件解压到ApacheWeb发布目录www/中。

2. 调用FCKeditor

新建一个PHP文件,并在程序中加载FCKeditor文件 include("FCKeditor/fckeditor.php"),然后加入初始化FCKeditord的各项配置。初始化及配置选项代码如下:

<?php
//加载入口文件
include("FCKeditor/fckeditor.php");
$oFCKeditor = new FCKeditor('FCKeditor1') ;//建立对象
$oFCKeditor->BasePath = 'FCKeditor/' ;//FCKeditor所在的位置
$oFCKeditor->ToolbarSet = 'Default' ;//工具按钮
$oFCKeditor->Value      = $row['Content'];
$oFCKeditor->Create('EditorDefault','60%',150) ;
?>

【代码解读】

以上的代码实例化编辑器类,并设置了FCKeditor编辑器的基本参数。通过$oFCKeditor->Value的方法,将文章内容部分输出到编辑器中。当编辑器中的内容改变后,再将内容变量更新到对应的数据库字段中,完成文本预览和编辑。完成上述功能的完整代码如下:

<?php
//文章索引id
$aid=$_GET['aid'];
if($aid){
        $con = mysqli_connect('localhost', 'root', 'root') or die('Could not connect: ' . mysqli_error());
        @mysqli_query("SET NAMES 'utf-8'",$con);//设定字符集编码
        //echo 'Connected successfully';
        $db=mysqli_select_db($con,'get_content');
        if (!$db){
        die ("Can\'t use download : " . mysqli_error());
        }else{
            // 获得文件详细信息
            $sql = "SELECT * FROM `articles` WHERE `ID` ='".$aid."' LIMIT 1 ";
            $result = mysqli_query($con,$sql);
            $row=mysqli_fetch_array($result);
            //var_dump ($row);
    }
}
 
$fck = $_POST [ "FCKeditor1" ] ;
if ( $fck != "" ) 
{ 
    $sql1 = "UPDATE `articles` SET `Content` = '".$fck."' WHERE `articles`.`ID` ='".$aid."' LIMIT  1; ";
    $result = mysqli_query($con,$sql1);
    if ($result) {
    // 释放结果集
    //mysqli_free_result($result);
        header("location:articles.php");

    }   
}
mysqli_close($con); 
?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
</head>
<link href="admin.css" rel="stylesheet" type="text/css" />
<base target="mainFrame">
<div class="m"></div>
<div class="t">
<table align=center cellspacing=0 cellpadding=0>
<form action="articles_save.php?aid=<?php echo $aid ;?>" method="post">
<tr class=head>
  <td colspan="2"><?php echo $row['Title']?></td>
</tr>
<tr class=line>
  <td width="9%">标题</td>
  <td width="91%"><input name="Title" type="text" class="input" id="Title" size="70" value="<?php echo $row['Title']?>" /></td>
</tr>
<tr class=line>
  <td valign="top">内容</td>
  <td>
<?php
//加载入口文件
include("FCKeditor/fckeditor.php");
//建立对象
$oFCKeditor = new FCKeditor('FCKeditor1') ;
//FCKeditor所在的位置
$oFCKeditor->BasePath = 'FCKeditor/' ;
//工具按钮
$oFCKeditor->ToolbarSet = 'Default' ;
$oFCKeditor->Value      = $row['Content'];
$oFCKeditor->Create('EditorDefault','60%',150) ;
?> 
  </td>
</tr>
<tr class=line>
  <td colspan="2" align="center">
    <input name="Submit" type="submit" class="btn" value="提交" />
    <input name="Submit" type="button" class="btn" value="返回" onclick="history.go(-1);" /></td>
  </tr>
</form>
</table>
</div>

注意:观察以上的代码,这段代码是通过程序获得$_GET[ID]的值(即文章的索引id)将对应文章的内容部分从数据库中取出提交到编辑器中,编辑内容的保存也是同样的原理。运行上面的代码,效果如图8.5所示。

image.png

图8.5FCKeditor内容编辑器

推荐