|
|
本帖最后由 thusboy 于 2010-11-7 10:42 编辑
建站目的:建立一个地方性贴吧,由于刚开始宣传困难,新人进来也没什么内容,来了就走了,因此就想采集百度贴吧的内容为自己的内容,留住新进访客。
达成效果:1. 初始采集我们市十县一区的百度吧主题和回帖,共计约20万条数据(生成评论后约100万条)
2. 数据真实性模拟,让90%普通用户看不出来内容是采集的,需要做到如下几点:
a: 虚拟1000个用户,并和随机匿名配合随机发帖。
b: 发帖和回帖的逻辑关系正确,回复数记录正确。
c: 定时更新每个目标贴吧前几页帖子,达到百度贴吧更新,我也更新。
实施日记:
step1: 编写采集规则
百度贴吧的采集规则其实是非常容易写的,每个内容都用了非常明确的html标签或者是明确的class,因此容易采集。难点有二:
1.采集发帖时间
发帖时间其实并不难,发帖时间的html代码是- <td class="info gray" colspan="2">
- <ul>
- <li>2010-11-5 11:02</li>
- <li><a onclick="Post.reply('1');" href="#sub">回复</a></li>
- </ul>
- </td>
复制代码 采集的方法可以用正则写成<td class="info gray" colspan="2">(*)<li>[参数]</li>(*)</td>
即可采集出时间,问题是在通过手机在百度贴吧发帖时,时间的html块里面混杂了一个别的li标签,使得采集有问题
用手机发帖的世间html块代码如下:- <td class="info gray" colspan="2">
- <ul>
- <li><a onclick="Statistics.sendRequest('fr=tb0_forum&st_type=phone_post_link&st_mod=pb')" href="http://www.baidu.com/search/post_wap.html">这条留言是通过手机发表的,我也要用手机发表留言!</a></li>
- <!--
- <li><a href="http://tieba.baidu.com/f?kz=891702603">此贴通过手机发表,中秋发贴赢大奖!</a></li>
- -->
- <li>2010-11-5 14:17</li>
- <li><a onclick="Post.reply('2');" href="#sub">回复</a></li>
- </ul>
- </td>
复制代码 这种代码使用刚开始写的规则显然是采集不出时间的,最后也没有想出来应该怎样写正则让两个都适用,最后使用了变通的方法,写正则:
<td class="info gray" colspan="2">(*)<li>20[参数]</li>(*)</td>
细心的朋友到看到了两个正则唯一的区别就是在[参数]前加了个20,也就是2010年的20,由于两种代码在外部标签在没有个识别的唯一性,因此只有借助这个20来定位要采集的内容。很明显这种采集是能够起作用的,但是唯一的缺陷就是把2010-11-5 12:00:32采集成了10-11-5 12:00:32
这个缺陷是非常容易解决的:
在发布内容的php插件(我用的是php,其它同理)时给时间标签添加字符串20
$LabelArray['时间'] = "20".$LabelArray['时间'];
2.回复采集
经过几天的研究发现采用主题-回复的网站模式只适用于发布模式,不适用于数据库导入模式,但是由于我需要导入的数据量比较大,显然采取发布的模式是行不通的。在帖子页循环采集出的内容,如果选择“添加为新纪录”将在入库中无法实现帖子主题表之间的逻辑关系,因此不可取,如果选择“用分隔符添加到上条记录上”
择所有回复也会附加到帖子内容后面,导入数据库自然是无法用的。由于火车头目前可以实现的功能知道做到这样,试来试去都无法达到我满意的效果,因此决定采用“用分隔符添加到上条记录上”先入库,然后再写一个php脚本把每条记录分割成内容和回复,然后再次入库,这样做有点麻烦,但是可以达到非常高的数据真实性,以下写出一个数据更新类的主程序流程的公用方法,给大家参考:-
- function public autoReply($fid){
- global $DB,$table_topic,$table_post2;
- $post=$DB->fetch_all("SELECT * FROM `".$table_post2."` WHERE `fid`=".$fid);
- foreach($post as $postitem){
- $reply = explode("|||",$postitem["message"]);
- $nowTopic = $this->getTopicInfo($postitem["tid"]);
- echo $nowTopic["lasttime_stamp"]."<br>";
- $i=0;
- foreach($reply as $replyitem){
- //echo $j."_".$i."_".$reply_num."<br />";
- if($i>0){
- $feedback["replies"] = $this->addreply($postitem["tid"],$postitem["fid"],$nowTopic["lasttime_stamp"],$replyitem);
- }
- else{
- $feedback["first"]= $this->updatefirstpost($postitem["tid"]);
- }
- $i++;
- }
- $reply_num = $nowTopic["replies"]+$i-1;
- $this->updateTopicinfo($feedback,$reply_num);
- $this->updatePostcontent($postitem["pid"],$reply[0]);
- }
- return $post;
- }
复制代码 今天先写到这,我的数据采集正在进行中,下一篇帖子将把我采集完毕的网站地址和工作截图发出来 |
评分
-
1
查看全部评分
-
|