php使用curl和正则表达式抓取网页数据示例


Posted in PHP onApril 13, 2014

利用curl和正则表达式做的一个针对磨铁中文网非vip章节的小说抓取器,支持输入小说ID下载小说。
依赖项:curl
可以简单的看下,里面用到了curl ,正则表达式,ajax等技术,适合新手看看。在本地测试,必须保证联网并且确保php开启curl的mode

SpiderTools.class.php

<?php

  session_start();

 //封装成类 开启这些自动抓取文章

  #header("Refresh:30;http://www.test.com:8080");

 class SpiderTools{ 

 //////////////////////////////////////////////////////////////////////////////////////////////////////////

 /*传入文章ID 解析出文章标题*/

 //////////////////////////////////////////////////////////////////////////////////////////////////////////

 public function getBookNameById($aid){

  //初始化curl

  $ch= curl_init();

  //url

  $url='http://www.motie.com/book/'.$aid;

  if(is_numeric($aid)){

  //正则表达式匹配

  $ru="/<h1\sclass=\"p-title\">\s*<a\shref=\"\/book\/\d+\">(.*)\s*<\/a>\s*<\/h1>/";

  }

  else{

  //<title>丧尸爆发之全家求生路_第一章  丧尸爆发  为吾友爱乐儿更新~_磨铁</title>

  $ru="/<title>(.*)<\/title>/";

  }

  //设置选项,包括URL

  curl_setopt($ch, CURLOPT_URL, $url);

  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//不自动输出内容

  curl_setopt($ch, CURLOPT_HEADER, 0);//不返回头部信息

  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 0); 

  //执行curl

  $output = curl_exec($ch);

  //错误提示

  if(curl_exec($ch) === false){

   die(curl_error($ch));

  }

  // 检查是否有错误发生

  if(curl_errno($ch)){

  echo 'Curl error: ' . curl_error($ch);

  }

  //释放curl句柄

  curl_close($ch);

  $arr=array();

  preg_match_all($ru,$output,$arr);

  return $arr[1][0];

   }

 //////////////////////////////////////////////////////////////////////////////////////////////////////////     

 /*传入文章ID  解析文章内容*/

 //////////////////////////////////////////////////////////////////////////////////////////////////////////

 public  function getBookContextById($aid){

  //开始解析文章

  $ids=array();

  $ids=explode("_",$aid);

  $titleId=trim($ids[0]);

  $aticleId=trim($ids[1]);

  $ch= curl_init();

  $ru="/<div class=\"page-content\">[\s\S]*<pre ondragstart=\"return false\" oncopy=\"return false;\" oncut=\"return false;\" oncontextmenu=\"return false\" class=\"note\" id=\"html_content_\d*\">[\s\S]*(.*)<img src=\"\/ajax\/chapter\/$titleId\/$aticleId\" class=\"hidden\" \/><\/pre>/ui"; 

  $url='http://www.motie.com/book/'.$aid;

  //正则表达式匹配
  //设置选项,包括URL

  curl_setopt($ch, CURLOPT_URL, $url);

  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//不自动输出内容

  curl_setopt($ch, CURLOPT_HEADER, 0);//不返回头部信息

  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 0); 

  //执行curl

  $output = curl_exec($ch);

  //错误提示

  if(curl_exec($ch) === false){

   die(curl_error($ch));

  }

  // 检查是否有错误发生

  if(curl_errno($ch)){

   echo 'Curl error: ' . curl_error($ch);

  }

  $arr=array();

  $arr2=array();

  preg_match_all($ru,$output,$arr);

  curl_close($ch);

  #var_dump($arr);

  $s=$arr[0][0];

  $s=substr($s,180);

  $arr2=explode("<img",$s);

  return trim($arr2[0]);

 }
 ////////////////////////////////////////////////////////////////////////////////////////////////////////// 

 /*静态方法 @生成小说文件 可以直接调用 */

 //////////////////////////////////////////////////////////////////////////////////////////////////////////

     public static function createBookById($id){

  

  if(!is_numeric($id)){
  echo "<br/>INIT BEGIN START WRITE!";

  $st=new self();

  $cons=$st->getBookContextById($id);

  $title=$st->getBookNameById($id);

  $cons=trim($cons);

  $t=explode(" ",$title);

  //构造目录

  $dir=array();

  $dir=explode("_",$t[0]);

  $wzdir=$dir[0];  //书名称 作为目录名称

  $wzchapter=$dir[1]; //第几章

  //创建目录

  $wzdir2=iconv("UTF-8", "GBK", $wzdir);//目录编码 注意这里保留对$wzdir字符串的引用,用来构造文件名,不能用此处,防止二次编码

  if(!file_exists($wzdir2)){

   mkdir($wzdir2); //创建目录

  }

  //构造文件名

  $wztitle="./".$wzdir."/"."$t[0]".".txt";

  //保证保存的文件名称不是乱码

  $wztitle=iconv("UTF-8", "GBK", $wztitle);

  $f=fopen($wztitle,"w+");

  fwrite($f,$cons);

  echo "<font color='green'>$wzdir </font>".$wzchapter."<font color='red'>写入成功</font>";

  fclose($f); 

  

  } 

  else{

  $ids=self::getBookIdsById($id); 

 

  //这里服务器可能会掉线,所以最好用session记录循环

  #for($i=$_SESSION["$id"."_fid"];$i<=count($ids);$_SESSION["$id"."_fid"]++,$i++){

 

   #self::createBookById($id."_".$ids[$_SESSION["$id"."_fid"]++]);//构造id

  #}

  

  for($i=$_SESSION["$id"."_fid"];$i<=count($ids);$_SESSION["$id"."_fid"]++,$i++){

 

   self::createBookById($id."_".$ids[$i]);//构造id

  }

  

  #echo "<hr/><hr/><br/><h1>写入工作全部完成</h1>";

  #echo $id."_".$ids[0]."<br/>"; 

  #var_dump($ids);

  

  }


 }

  /*

  获取小说的所有ID

  @param $id 文章ID

  @return array;

  */

  public static function getBookIdsById($aid){ 

  $ch= curl_init();

  $url='http://www.motie.com/book/'.$aid."/chapter";

  //注意这里的?可以获取最少匹配项

  $ru='/[\s\S]*?<li class=\"\" createdate=\"\d{4}\-\d{2}\-\d{2} \d{2}:\d{2}:\d{2}\">[\s\S]*?<a href=\"\/book\/'.$aid.'_(\d*?)\"\s{1}>.*?<\/a>.*?/u';//正则表达式匹配

  //设置选项,包括URL

  curl_setopt($ch, CURLOPT_URL, $url);

  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//不自动输出内容

  curl_setopt($ch, CURLOPT_HEADER, 0);//不返回头部信息

  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 0); 

  //执行curl

  $output = curl_exec($ch);

  // 检查是否有错误发生

  if(curl_errno($ch)){

  echo 'Curl error: ' . curl_error($ch);

  }

  //释放curl句柄

  curl_close($ch);

  $arr=array();

  preg_match_all($ru,$output,$arr,PREG_PATTERN_ORDER);

  return $arr[1];

  }

}

?>

getinfo.php

<?php

 session_start();

require_once("SpiderTools.class.php");

if($_REQUEST["bid"]){

if(is_numeric($_REQUEST["bid"])){

 SpiderTools::createBookById(trim($_REQUEST["bid"]));

 }

 else{

  echo "<br/>请输入正确的文章ID<br/>";

 }

}

?>

index.html

<html>

<head><meta charset="utf-8"/></head>

<title>下载小说啦</title>

<body>

<h1>输入磨铁中文网你想看到的小说ID号就可以下载小说啦</h1>

<form method="get" action="getinfo.php">

<input type="text" id="myid" name="myid" value=""/>

<input type="button" value="生成小说" onclick="createbook();"/>

</form>

<div id="info" style="background:black;height:500px;width:1067px;overflow:scroll;color:white">

</div>
<!-----AJAX------>

<script language="javascript">

var xmlHttp;

function createbook()

{

xmlHttp=GetXmlHttpObject()

if (xmlHttp==null)

 {

 alert ("浏览器不支持ajax")

 return

 }

var bookid=document.getElementById("myid").value

var url="getinfo.php"

url=url+"?bid="+bookid;

url=url+"&sid="+Math.random()

xmlHttp.onreadystatechange=stateChanged 

xmlHttp.open("GET",url,true)

xmlHttp.send(null)

}
function stateChanged() 

{ 

if(xmlHttp.readyState==1){
 document.getElementById("info").innerHTML="正在准备工作,请耐心点哦~^_^~<img src=\"img/1.gif\"  /><br/>"; 

} 

if(xmlHttp.readyState==2){
 document.getElementById("info").innerHTML="正在联系服务器,这可能需要一点时间啦^><img src=\"img/2.gif\"  /><^<br/>"; 

}
if(xmlHttp.readyState==3){
 document.getElementById("info").innerHTML="正在解析数据<img src=\"img/3.gif\"  /><br/>"; 

}
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")

 { 

 

 document.getElementById("info").innerHTML=xmlHttp.responseText; 

 //xmlHttp.abort();
 
 }


}
function GetXmlHttpObject()

{

var xmlHttp=null;

try

 {

 // Firefox, Opera 8.0+, Safari

 xmlHttp=new XMLHttpRequest();

 }

catch (e)

 {

 //Internet Explorer

 try

  {

  xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");

  }

 catch (e)

  {

  xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");

  }

 }

return xmlHttp;

}

</script>

</body>

</html>
PHP 相关文章推荐
用PHP连mysql和oracle数据库性能比较
Oct 09 PHP
PHP与SQL注入攻击防范小技巧
Sep 16 PHP
ThinkPHP中redirect用法分析
Dec 05 PHP
PHP判断浏览器、判断语言代码分享
Mar 05 PHP
php实现的一个简单json rpc框架实例
Mar 30 PHP
Laravel 5框架学习之数据库迁移(Migrations)
Apr 08 PHP
PHP session文件独占锁引起阻塞问题解决方法
May 12 PHP
实例简介PHP的一些高级面向对象编程的特性
Nov 27 PHP
动态表单验证的操作方法和TP框架里面的ajax表单验证
Jul 19 PHP
PHP 7.4中使用预加载的方法详解
Jul 08 PHP
Laravel5.4简单实现app接口Api Token认证方法
Aug 29 PHP
php实现图片压缩处理
Sep 09 PHP
PHP header()函数常用方法总结
Apr 11 #PHP
开源php中文分词系统SCWS安装和使用实例
Apr 11 #PHP
PHP获取网页标题的3种实现方法代码实例
Apr 11 #PHP
PHP动态生成javascript文件的2个例子
Apr 11 #PHP
php实现数组筛选奇数和偶数示例
Apr 11 #PHP
php求正负数数组中连续元素最大值示例
Apr 11 #PHP
PHP入门经历和学习过程分享
Apr 11 #PHP
You might like
PHP URL地址获取函数代码(端口等) 推荐
2010/05/15 PHP
编译php 5.2.14+fpm+memcached(具体操作详解)
2013/06/18 PHP
php调用nginx的mod_zip模块打包ZIP文件
2014/06/11 PHP
Zend Framework实现多服务器共享SESSION数据的方法
2016/03/22 PHP
PHP读取XML文件的方法实例总结【DOMDocument及simplexml方法】
2019/09/10 PHP
百度 popup.js 完美修正版非常的不错 脚本之家推荐
2009/04/17 Javascript
javascript编码的几个方法详细介绍
2013/01/06 Javascript
JS调用页面表格导出excel示例代码
2014/03/18 Javascript
js实现点击图片改变页面背景图的方法
2015/02/28 Javascript
JS显示下拉列表框内全部元素的方法
2015/03/31 Javascript
jquery Ajax 全局调用封装实例详解
2017/01/16 Javascript
图文详解Javascript中的上下文和作用域
2017/02/15 Javascript
Angular.js中数组操作的方法教程
2017/07/31 Javascript
Node.js学习之地址解析模块URL的使用详解
2017/09/28 Javascript
微信小程序 功能函数小结(手机号验证*、密码验证*、获取验证码*)
2017/12/08 Javascript
微信小程序使用picker实现时间和日期选择框功能【附源码下载】
2017/12/11 Javascript
vue中动态设置meta标签和title标签的方法
2018/07/11 Javascript
基于ajax及jQuery实现局部刷新过程解析
2020/09/12 jQuery
理解JavaScript中的Proxy 与 Reflection API
2020/09/21 Javascript
解决Ant Design Modal内嵌Form表单initialValue值不动态更新问题
2020/10/29 Javascript
详解JavaScript执行模型
2020/11/16 Javascript
Python用模块pytz来转换时区
2016/08/19 Python
详解基于python的多张不同宽高图片拼接成大图
2019/09/26 Python
美国转售二手商品的电子商务平台:BLINQ
2018/12/13 全球购物
杭州SQL浙江浙大网新恩普软件有限公司
2013/07/27 面试题
大学生的创业计划书就该这么写
2014/01/30 职场文书
应聘医药销售自荐书范文
2014/02/08 职场文书
高考备战决心书
2014/03/11 职场文书
导师推荐信范文
2014/05/09 职场文书
敬老院标语
2014/06/27 职场文书
群众路线教育实践活动批评与自我批评
2014/09/15 职场文书
学习计划书怎么写
2014/09/15 职场文书
2014党员自我评议表范文
2014/09/20 职场文书
结婚典礼致辞
2015/07/28 职场文书
2019年度政务公开考核工作总结模板
2019/11/11 职场文书
《遗弃》开发商删推文要跑路?官方回应:还在开发
2022/04/03 其他游戏