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制作静态网站的模板框架
Oct 09 PHP
第七章 php自定义函数实现代码
Dec 30 PHP
ubuntu12.04使用c编写php扩展模块教程分享
Dec 25 PHP
php去除html标记的原生函数详解
Jan 27 PHP
经典PHP加密解密函数Authcode()修复版代码
Apr 05 PHP
php通过curl添加cookie伪造登陆抓取数据的方法
Apr 02 PHP
PHP中使用foreach()遍历二维数组的简单实例
Jun 13 PHP
PHP解压ZIP文件到指定文件夹的方法
Nov 17 PHP
浅谈socket同步和异步、阻塞和非阻塞、I/O模型
Dec 15 PHP
php使用preg_match()函数验证ip地址的方法
Jan 07 PHP
Laravel如何使用Redis共享Session
Feb 23 PHP
laravel 执行迁移回滚示例
Oct 23 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中如何直接执行SHELL
2013/06/28 PHP
php数组随机排序实现方法
2015/06/13 PHP
php投票系统之增加与删除投票(管理员篇)
2016/07/01 PHP
php接口隔离原则实例分析
2019/11/11 PHP
php设计模式之适配器模式实例分析【星际争霸游戏案例】
2020/04/07 PHP
JavaScript 原型与继承说明
2010/06/09 Javascript
原生js实现跨浏览器获取鼠标按键的值
2013/04/08 Javascript
让人蛋疼的JavaScript语法特性
2014/09/30 Javascript
jQuery实现提交按钮点击后变成正在处理字样并禁止点击的方法
2015/03/24 Javascript
javascript实现input file上传图片预览效果
2015/12/31 Javascript
JS实现消息来时让网页标题闪动效果的方法
2016/04/20 Javascript
jQuery实现背景滑动菜单
2016/12/02 Javascript
JavaScript中捕获/阻止捕获、冒泡/阻止冒泡方法
2016/12/07 Javascript
工厂模式在JS中的实践
2017/01/18 Javascript
详解如何提高 webpack 构建 Vue 项目的速度
2017/07/03 Javascript
vue项目持久化存储数据的实现代码
2018/10/01 Javascript
Vue模板语法中数据绑定的实例代码
2019/05/17 Javascript
编写v-for循环的技巧汇总
2020/12/01 Javascript
vue3.0实现插件封装
2020/12/14 Vue.js
[31:01]2014 DOTA2国际邀请赛中国区预选赛5.21 CNB VS Orenda
2014/05/23 DOTA
Python 命令行非阻塞输入的小例子
2013/09/27 Python
Python实现的检测网站挂马程序
2014/11/30 Python
python妙用之编码的转换详解
2017/04/21 Python
python实现协同过滤推荐算法完整代码示例
2017/12/15 Python
使用django-crontab实现定时任务的示例
2018/02/26 Python
Python GUI编程 文本弹窗的实例
2019/06/11 Python
Django之创建引擎索引报错及解决详解
2019/07/17 Python
cProfile Python性能分析工具使用详解
2019/07/22 Python
CSS3样式linear-gradient的使用实例
2017/01/16 HTML / CSS
毕业生应聘幼儿园的自荐信
2013/11/20 职场文书
员工团队活动方案
2014/08/28 职场文书
2014年人民调解工作总结
2014/12/08 职场文书
教学质量月活动总结
2015/05/11 职场文书
教你用Python爬取英雄联盟皮肤原画
2021/06/13 Python
关于Python中进度条的六个实用技巧分享
2022/04/05 Python
如何使用SQL Server语句创建表
2022/04/12 SQL Server