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 相关文章推荐
我的论坛源代码(四)
Oct 09 PHP
php目录操作函数之获取目录与文件的类型
Dec 29 PHP
PHP中几个常用的魔术常量
Feb 23 PHP
探讨:如何使用PHP实现计算两个日期间隔的年、月、周、日数
Jun 13 PHP
thinkphp 一个页面使用2次分页的实现方法
Jul 15 PHP
PHP文件大小格式化函数合集
Mar 10 PHP
PHP三元运算的2种写法代码实例
May 12 PHP
CentOS安装php v8js教程
Feb 26 PHP
php生成验证码函数
Oct 20 PHP
weiphp微信公众平台授权设置
Jan 04 PHP
PHP封装类似thinkphp连贯操作数据库Db类与简单应用示例
May 08 PHP
Laravel框架实现多个视图共享相同数据的方法详解
Jul 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实现删除指定目录下相关文件的方法
2014/10/20 PHP
PHP大文件分块上传功能实例详解
2019/07/22 PHP
DEFER怎么用?
2006/07/01 Javascript
javascript支持firefox,ie7页面布局拖拽效果代码
2007/12/20 Javascript
5个最佳的Javascript日期处理类库分享
2012/04/15 Javascript
精心挑选的12款优秀的基于jQuery的手风琴效果插件和教程
2012/08/22 Javascript
说说JSON和JSONP 也许你会豁然开朗
2012/09/02 Javascript
javascript对下拉列表框(select)的操作实例讲解
2013/11/29 Javascript
js清空表单数据的两种方式(遍历+reset)
2014/07/18 Javascript
超级好用的jQuery圆角插件 Corner速成
2014/08/31 Javascript
AngularJS 实现按需异步加载实例代码
2015/10/18 Javascript
JavaScript中使用Async实现异步控制
2017/08/15 Javascript
深入浅出es6模板字符串
2017/08/26 Javascript
Vue的百度地图插件尝试使用
2017/09/06 Javascript
基于wordpress的ajax写法详解
2018/01/02 Javascript
解决Vue在封装了Axios后手动刷新页面拦截器无效的问题
2018/11/08 Javascript
[01:24]DOTA2上海特锦赛OG战队抵达 专车接机入驻总统套房
2016/02/23 DOTA
使用Python标准库中的wave模块绘制乐谱的简单教程
2015/03/30 Python
Python使用SocketServer模块编写基本服务器程序的教程
2016/07/12 Python
Python3.4编程实现简单抓取爬虫功能示例
2017/09/14 Python
Python语言描述随机梯度下降法
2018/01/04 Python
利用pandas合并多个excel的方法示例
2019/10/10 Python
pytorch GAN生成对抗网络实例
2020/01/10 Python
Tensorflow的梯度异步更新示例
2020/01/23 Python
python操作docx写入内容,并控制文本的字体颜色
2020/02/13 Python
python3的pip路径在哪
2020/06/23 Python
Python延迟绑定问题原理及解决方案
2020/08/04 Python
HTML5中FileReader接口使用方法实例详解
2017/08/26 HTML / CSS
浅析HTML5的WebSocket与服务器推送事件
2016/02/19 HTML / CSS
电子商务专业个人的自我评价
2013/12/19 职场文书
师说教学反思
2014/02/07 职场文书
感恩父母主题班会
2015/08/12 职场文书
重阳节主题班会
2015/08/17 职场文书
小学教代会开幕词
2016/03/04 职场文书
创业计划书之淘宝网店
2019/10/08 职场文书
详解Flutter自定义应用程序内键盘的实现方法
2022/06/14 Java/Android