当前位置: 移动技术网 > IT编程>开发语言>PHP > php使用curl和正则表达式抓取网页数据示例

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

2019年03月28日  | 移动技术网IT编程  | 我要评论

利用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/>";
 }
}
?>


复制代码 代码如下:

<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>

ps:关于正则,这里再为大家推荐2款本站的正则表达式在线工具供大家参考使用(包括正则生成、匹配、验证等功能):

javascript正则表达式在线测试工具:

正则表达式在线生成工具:

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网