数据采集之file_get_contents实现

由于需要一些新闻的信息,比如标题、时间、作者、内容和图片等信息。之前听说过数据采集,所以想尝试一下,结果花了大半天的时间才基本上完成了。当然了,bug肯定还是有的。

下面介绍我实现新闻采集的过程:

首先,肯定要找一个新闻网站,我选择的是中国新闻网,最好是选择有新闻列表的页面(比如:http://www.chinanews.com/scroll-news/gn/2015/1021/news.shtml)。选择有新闻列表的页面,可以抓取多个页面的url。然后通过这些url去获取详细页面的标题、时间等信息。

然后,获取新闻列表的url。先要分析该页面,通过字符串函数(substr、strpos等)截取列表部分;再通过正则表达式获取各个子页面的连接。

最后,分析子页面的结构,通过字符串函数截取包括标题(时间等)的代码,通过正则表达式得到想要的信息。其中包括将数据插入数据库以及下载相应的图片到本地。

下面附上我的代码,里面有详细的说明。

<?php
	set_time_limit(0);
	header("Content-Type:text/html;charset=utf-8");
	$str = file_get_contents("http://www.chinanews.com/scroll-news/gn/2015/1021/news.shtml");

	//用字符串函数实现,具体见	function sub_string($str,$start,$end)
	//截取父页面列表的开头和结尾
	$start = '<div class="content_list">';
	$end = '<div id="footerAd"';
	//得到的结果
	$need = sub_string($str,$start,$end);
	

	$re = '/<a.*href=("|\')(.+)\1.*>.+<\/a>/U';  
	// U:非贪婪匹配 , \1反向引用第一个括号中的内容

	//$a是正则匹配获取的全部内容
	//$a[0] 是获取的每一个匹配
	//$a[1] 是第一个匹配子组(对应的是("|\'))
	//$a[2] 是第二个匹配子组(对应的就是(.+))
	preg_match_all($re, $need, $a);

	// 连接数据库
	$link = mysql_connect("localhost:3306","root","root");
	if(!$link)
		die("连接数据库失败");
	if(!mysql_select_db("rain"))
		die("选择数据库失败");

	foreach ($a[2] as $value) {
		//暂时只发现了连接的两种情况
		//1.没有主域名,如:/gn/2015/11-07/7610858.shtml
		if(strpos($value,"http://www.chinanews.com/") === false)
		{
			//这里是用“.”,刚开始用的加号,一直没找出来问题
			$newvalue = "http://www.chinanews.com" . $value;

			//获取子页面
			$sub_str = file_get_contents("{$newvalue}");			
		}	

		//2.完整url连接,如:http://www.chinanews.com/gn/2015/11-07/7610858.shtml
		if (preg_match("/^http:\/\/www\.chinanews\.com\/[a-z]{2}\/\d{4}.*/", $value) ) 
		{
			//获取子页面
			$sub_str = file_get_contents("{$value}");			
		}

		//将整个字符串转码为utf-8
		$sub_str = iconv("GBK", "UTF-8", $sub_str);

		//获取标题
		$title = sub_title($sub_str) ;
		
		//作者
		preg_match('/<a.*>(.*)<\/a>/', sub_author($sub_str),$sub_a);
		$author = $sub_a[1];

		//内容
		$content = sub_content($sub_str);
		$content = mysql_escape_string($content);

		//日期
		$time = sub_time($sub_str);
		//将中文 年 月 换成 -
		preg_match('/\d{4}[\x{4e00}-\x{9fa5}]\d{2}[\x{4e00}-\x{9fa5}]\d{2}/u', $time,$sub_a);
		$time = preg_replace("/[\x{4e00}-\x{9fa5}]/u", "-", $sub_a[0]);

		//日期
		$picture = sub_picture($sub_str);
		if(isset($picture))
		{
			preg_match('/<img.*src=("|\')(.*)\1.*alt.*\/>/', $picture,$pic);
			$picture = $pic[2];
			//获取图片名称
			$pic_name = substr($picture, strrpos($picture, "/")+1) ;

			//存放图片的路径
			$path = "./";
			//写入图片
			file_put_contents($path . $pic_name, file_get_contents($picture));
			//更改存入数据库的文件名
			$picture = $pic_name;
		}

		//插入语句
		$sql = "insert into rain_news values(null,1,1,'{$title}','{$time}','{$picture}','{$author}','{$content}')";

		//如果出错,显示错误信息
		if(!mysql_query($sql))
		{
			echo mysql_error();
			echo "<hr>";
		}
	}


	//在原字符串中截取指定开头和结尾间的内容返回
	function sub_string($str,$start,$end)
	{
		$s = strpos($str, $start);
		$e = strpos($str, $end);
		$need = substr($str, $s , $e - $s);
		return $need;
	}
	//以下函数只适应中新网的新闻详细页面的信息获取
	//截取标题
	function sub_title($str)
	{
		$start = '<h1 style="display:block; position:relative; text-align:center; width:624px;clear:both">';
		$end = '</h1>';
		$s = strpos($str, $start) + strlen($start);
		$e = strpos($str, $end);		
		return substr($str, $s , $e - $s);
	}//<span id="author_baidu">作者:

	//截取作者
	function sub_author($str)
	{
		$start = '<span id="source_baidu">';
		$end = '<span id="author_baidu">';
		$s = strpos($str, $start) + strlen($start);
		$e = strpos($str, $end);		
		return substr($str, $s , $e - $s);
	}

	//获取新闻内容
	function sub_content($str)
	{
		 $start = '<div class="left_zw" style="position:relative">';
		 $end = '<table border=0 cellspacing=0 cellpadding=0 align=left style="padding-right:10px;">';
		 $s = strpos($str, $start) + strlen($start);
		 $e = strpos($str, $end);		
		 return substr($str, $s , $e - $s);		 
	}
	//获取时间
	function sub_time($str)
	{
		$start = '<div class="left-t" style="padding-left:6px;">';
		 $end = '<div class="bshare-custom" style="width:185px;">';
		 $s = strpos($str, $start) + strlen($start);
		 $e = strpos($str, $end);		
		 return substr($str, $s , $e - $s);			
	}

	//获取图片信息
	function sub_picture($str)
	{
		 $start = '<div class=left_ph>';
		 $end = '<div class=left_pt>';		 
		 $s = strpos($str, $start) + strlen($start);
		 $e = strpos($str, $end);	
		 if($e === false)
		 {
		 	return null;
		 }	
		 return substr($str, $s , $e - $s);			
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值