基于php编写的新闻类爬虫,插入WordPress数据库
这个爬虫写的比较久远,很久没有更新博客了。
1.首先思路是:通过php的curl_setopt()函数可以方便快捷的抓取网页。
2.什么样的新闻吸引人呢,当然的热点新闻了。这里选百度的搜索风云榜,获取热点关键词列表。
3.为了方便过滤,我们筛选搜狐的新闻。由于搜狐是通过搜狗搜索的新闻。所以把百度热点关键词通过搜狗一一搜索,打开对应的结果,筛选出搜狐的新闻链接。
4.进入搜狐新闻。获取新闻数据,进行内容筛选,重复过滤。
5.插入WordPress数据库,得到自己的新闻链接
6.自己的新闻链接主动提交给百度收录。
spider.class.php
1 <?php 2 //网页爬虫 3 class spider{ 4 public $curl; 5 public $timeout = 5; 6 //尝试请求链接的时间 7 public $data; 8 public $fromUrl; 9 //初始化 10 public function __construct($url) {//构造函数 11 $this -> fromUrl=$url; 12 $this -> curl = curl_init(); 13 //相当于header里的Accept-Encoding>>防止乱码 14 curl_setopt($this -> curl, CURLOPT_ENCODING, ""); 15 // 设置你需要抓取的URL 16 curl_setopt($this -> curl, CURLOPT_URL, $url); 17 // 设置header 18 curl_setopt($this -> curl, CURLOPT_HEADER, 0); 19 // 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。如果希望获得内容但不输出,使用 CURLOPT_RETURNTRANSFER参数,并设为非0值/true! 20 curl_setopt($this -> curl, CURLOPT_RETURNTRANSFER, 1); 21 //参数CURLOPT_CONNECTTIMEOUT 通常用来设置curl尝试请求链接的时间 22 curl_setopt($this -> curl, CURLOPT_CONNECTTIMEOUT, $this -> timeout); 23 // CURLOPT_USERAGENT,它允许你自定义请求是的客户端名称, 24 curl_setopt($this -> curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36'); 25 // 运行cURL,请求网页 26 $this -> data = curl_exec($this -> curl); 27 if($this -> data){ 28 $wcharset = preg_match("/<meta.+?charset=[^\w]?([-\w]+)/i",$this -> data,$temp) ? strtolower($temp[1]):"";//获取网页编码 29 if($temp[1]!='utf-8' && $temp[1]!=''){ 30 $this -> data = iconv($temp[1], "utf-8//IGNORE", $this -> data);//转换成utf8 31 } 32 33 }else{ 34 return FALSE; 35 } 36 } 37 } 38 39 ?>
mysql.class.php
1 <?php 2 //数据库操作 3 header('Content-Type: text/html; charset=UTF-8'); 4 $conn = mysql_connect("10.10.10.10","",""); 5 mysql_select_db('cn_bjxxw_wenzhang'); 6 mysql_query("set names utf8"); 7 if (!$conn){ 8 die('数据库连接失败: ' . mysql_error()); 9 } 10 class mysqlJi{//数据库 11 static function mysqlQu($sql){//sql语句 12 return mysql_query($sql); 13 } 14 static function mysqlFeAs($result){//遍历结果 15 $i=0;//变量i 16 while($row = mysql_fetch_assoc($result)){ 17 $reslist[$i] =$row; 18 $i++; 19 } 20 return $reslist; 21 } 22 static function jsonEn($reslist){//输出json 23 echo json_encode($reslist); 24 } 25 static function mysqlRows(){ //受影响的行数 26 $info_str = mysql_info(); //函数返回最近一条查询的信息。如果成功,则返回有关该语句的信息,如果失败,则返回 false 27 $a_rows = mysql_affected_rows(); //受影响的行数 28 preg_match("([0-9]*)", $info_str, $r_matched); 29 return ($a_rows < 1)?($r_matched[1]?$r_matched[1]:0):$a_rows; 30 31 } 32 static function insertId(){//最后一条记录的ID 33 $getID=mysql_insert_id();//$getID即为最后一条记录的ID 34 return $getID; 35 } 36 static function mysqlCl(){//关闭数据库 37 mysql_close(); 38 } 39 } 40 ?>
baiduPush.class.php
1 <?php 2 //百度收录主动提交 3 class baiduPush{ 4 public $result;//返回结果 5 public function __construct($urls,$api){//构造函数//(传递数组,api ) 6 $ch = curl_init(); 7 $options = array( 8 CURLOPT_URL => $api, 9 CURLOPT_POST => true, 10 CURLOPT_RETURNTRANSFER => true, 11 CURLOPT_POSTFIELDS => implode("\n", $urls), 12 CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), 13 ); 14 curl_setopt_array($ch, $options); 15 $this->result = curl_exec($ch); 16 } 17 } 18 19 ?>
info.php
1 <?php 2 //本页为获取新闻详情页面 3 include ("mysql.class.php");//引入数据库相关 4 date_default_timezone_set("PRC");//时区 5 include ("spider.class.php"); 6 include("baiduPush.class.php"); 7 class spider_cont extends spider{ 8 public $title = array();//被过滤后的标题 9 public $stime = array();//被过滤后的时间 10 public $screenData = array();//被过滤的内容 11 public $classNew;//新闻分类 12 //数据过滤(html标签,属性id class,属性值)//搜狐新闻 13 function sohuCon($fenlei){ 14 15 if (preg_match('/top\-pager\-current/',$this->data,$if_page1)) { 16 print "------数据放空"; 17 } else { 18 19 preg_match('/<div[^>]*itemprop="articleBody"[^>]*>(.*?) seo/si',$this->data,$this->screenData); 20 if($this->screenData[0]==''){ 21 //取出 div 标签且 id 为 contentText 的內容,并储存至二维数组 $screenData 中 22 preg_match('/<div[^>]*id="contentText"[^>]*>(.*?) seo/si',$this->data,$this->screenData); 23 if($this->screenData[0]==''){ 24 preg_match('/<div[^>]*id="contentText"[^>]*>(.*?) -->/si',$this->data,$this->screenData); 25 preg_match_all('/<h1(.*?)>(.*?)<\/h1>/si',$this->data,$tit2);//标题 26 $this->title[0]=$tit2[0][1]; 27 }else{ 28 preg_match('/<h1(.*?)>(.*?)<\/h1>/si',$this->data,$this->title);//标题 29 30 } 31 }else{ 32 preg_match('/<h1(.*?)>(.*?)<\/h1>/si',$this->data,$this->title);//标题 33 34 } 35 36 37 //过滤标签 38 $this->screenData[0]=preg_replace("/media_span_url\(\'(.*?)\'\)/si","",$this->screenData[0]); //过滤head标签 单独过滤 39 $this->screenData[0]=$this->guolv($this->screenData[0], "<img><div><span><p>"); //内容过滤 40 41 $this->title[0]=$this->guolv($this->title[0], ""); //标题过滤 42 preg_match('/<span itemprop="name">(.*?)<\/span>/si',$this->data,$laiyuan);//来源 43 $g_laiyuan=$this->guolv($laiyuan[0], ""); //来源过滤 44 if($this->screenData[0] && $this->title[0] && $g_laiyuan!="新京报"){ 45 //数据库执行 46 $atime=date('y-m-d H:i:s',time()); 47 $this->sqlDo($this->title[0],$atime,$this->screenData[0],$g_laiyuan,$this->fromUrl,$fenlei); 48 49 }else{ 50 echo $this->title[0].$g_laiyuan."-----数据为空<br>"; 51 } 52 } 53 } 54 //数据语句操作--- 对应的WordPress数据库 55 function sqlDo($atitle,$atime,$acontent,$fromName,$biaoshi,$fenlei){//(文章标题,时间,内容,来源名,来源标识url,分类) 56 57 $getBiaoshi=mysqlJi::mysqlQu("SELECT COUNT(*) as biaoshi FROM `wp_posts` WHERE post_content_filtered='{$biaoshi}';"); 58 $acount=mysqlJi::mysqlFeAs($getBiaoshi);//查找数据库是否已经存在该数据 59 if($acount[0]['biaoshi']==0){ 60 $res=mysqlJi::mysqlQu("INSERT INTO `wp_posts` (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count`, `laiyuan`, `description`) VALUES ('', '9192206', '{$atime}', '{$atime}', '{$acontent}', '{$atitle}', '', 'publish', 'open', 'open', '', '%e6%9e%81%e5%8c%96%e6%b3%a2', '', '', '{$atime}', '{$atime}', '{$biaoshi}', '0', '', '0', 'post', '', '0', '{$fromName}', '')");//sql语句 61 $rows=mysqlJi::mysqlRows();//受影响的行数 62 if($rows==1){ 63 $inid=mysqlJi::insertId();//最后一条记录的ID 64 $urls = array('http://wenzhang.bjxxw.com/archives/'.$inid.'.html');//提交地址 65 $baiduApi = 'http://data.zz.baidu.com/urls?site=wenzhang.bjxxw.com&token=GKEJ4ENj4i6PMu51';//百度api 66 $aBaiduPush= new baiduPush($urls,$baiduApi); //百度自动提交 67 echo $aBaiduPush->result; 68 $res2=mysqlJi::mysqlQu("INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`) VALUES ('{$inid}', '{$fenlei}')");//sql语句 69 $rows2=mysqlJi::mysqlRows();//受影响的行数 70 echo $atitle."----来源".$fromName."----插入id为".$inid."----成功<br>"; 71 }else{ 72 echo $atitle."----来源".$fromName."----失败<br>"; 73 } 74 }else{ 75 echo "--数据库已经有啦--"; 76 } 77 } 78 //过滤所有html标签(数据,除了哪些标签) 79 function guolv($data,$chule){ 80 return strip_tags($data,$chule);//除了img标签 81 } 82 //结束 83 function __destruct(){ 84 curl_close($this->curl); 85 } 86 } 87 //$aNewcont= new spider_cont("http://mil.sohu.com/20160905/n467640017.shtml"); 88 //$aNewcont->sohuCon(3013); 89 90 ?>
getRollNews.php
1 <?php 2 //本页为新闻列表获取也面 3 //引入详情页 4 include ("info.php"); 5 ///网页爬虫列表 6 class spider_list extends spider { 7 //新闻列表 8 function screen_list($zhengze, $fenlei) { 9 $this -> data = $this -> guolv($this -> data, '<td>'); 10 //过滤所有html标签(数据,除了哪些标签) 11 $this -> data = preg_replace("/search/si", "", $this -> data); 12 //过滤head标签 单独过滤 13 //过滤筛选 14 preg_match_all($zhengze, $this -> data, $regArr, PREG_SET_ORDER); 15 //定义一维数组 16 $array = array(); 17 for ($i = 0; $i < count($regArr); $i++) {//二维数组转一维数组 18 $array[$i] = $regArr[$i][0]; 19 } 20 //去除重复 21 $array = array_unique($array); 22 //去除数组键名 23 $array = array_values($array); 24 for ($i = 0; $i < count($array); $i++) {//找出所有匹配的链接 25 //网址列表目录 26 if ($array[$i]) { 27 // //执行内容获取 28 $sohuList = "/http:\/\/([\.a-z]+)\.sohu\.com\/20(\d+)\/n(\d+)\.shtml/"; 29 //搜狐列表过滤规则 30 $new = strip_tags($array[$i]); 31 //去除html标记 32 $new = trim($new); 33 //去空格 34 echo "<hr>".($i+1)."通过:<em>" . $new . "</em> 搜索到::"; 35 $ser = rawurlencode($new); 36 //转换成url 37 $sohuUrl = new spider_sohu("http://news.sogou.com/news?query=site%3Asohu.com+" . $ser); 38 $sohuUrl -> screen_list($sohuList, $fenlei); 39 } 40 } 41 42 } 43 44 //过滤所有html标签(数据,除了哪些标签) 45 function guolv($data, $chule) { 46 return strip_tags($data, $chule); 47 } 48 49 //结束 50 function __destruct() { 51 curl_close($this -> curl); 52 } 53 54 } 55 56 ///网页爬虫列表 57 class spider_sohu extends spider { 58 //新闻列表 59 function screen_list($zhengze, $fenlei) { 60 61 preg_match('/<h3 class="vrTitle">(.*?)<\/h3>/si', $this -> data, $gulv1); 62 //过滤 63 $this -> data = $this -> guolv($gulv1[0], '<a><h3>'); 64 //过滤所有html标签(数据,除了哪些标签) 65 66 // var_dump($laiyuan[0]); 67 //过滤筛选 68 preg_match($zhengze, $this -> data, $regArr); 69 echo $regArr[0]."<br>"; 70 $aNewcont= new spider_cont($regArr[0]); 71 $aNewcont->sohuCon($fenlei); 72 } 73 74 //过滤所有html标签(数据,除了哪些标签) 75 function guolv($data, $chule) { 76 return strip_tags($data, $chule); 77 } 78 79 //结束 80 function __destruct() { 81 curl_close($this -> curl); 82 } 83 84 } 85 86 $baiduList = '/<td[^>]*class="keyword">(.*?)<\/td>/si'; 87 //百度列表过滤规则 88 //$aNewList = new spider_list('http://top.baidu.com/buzz?b=42&c=513&fr=topbuzz_b341_c513'); 89 //$aNewList -> screen_list($baiduList, 239); 90 91 $NewUrls = array( 92 array('aid'=>3021,'aurl'=>'http://top.baidu.com/buzz?b=344&c=513&fr=topbuzz_b42_c513','aname'=>'娱乐'),//0 93 array('aid'=>2585,'aurl'=>'http://top.baidu.com/buzz?b=341&c=513&fr=topbuzz_b1_c513','aname'=>'今日热点'),//1 94 array('aid'=>2585,'aurl'=>'http://top.baidu.com/buzz?b=1&c=513&fr=topbuzz_b344_c513','aname'=>'热点'),//2 95 array('aid'=>2585,'aurl'=>'http://top.baidu.com/buzz?b=42&c=513&fr=topbuzz_b341_c513','aname'=>'热点'),//3 96 ); 97 98 for ($i = 0; $i < count($NewUrls); $i++) {//找出所有匹配的链接 99 echo "<br>-----------分类-----------".$NewUrls[$i]['aname']."------------<br>"; 100 $aNewList = new spider_list($NewUrls[$i]['aurl']); 101 $aNewList->screen_list($sohuList,$NewUrls[$i]['aid']); 102 } 103 //关闭数据库 104 mysqlJi::mysqlCl(); 105 106 ?>
后来加入了新闻内同义词自动替换。发现替换后,新闻阅读起来太伤眼,已弃之。