欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-30 08:22:30
利用curl和正则表达式做的一个针对磨铁中文网非vip章节的小说抓取器,支持输入小说id下载小说。 依赖项:curl 可以简单的看下,里面用到了curl ,正则表达式,...

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

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

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

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