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

这篇文章主要介绍了php使用curl和正则表达式抓取网页数据示例,这里是抓取某网站的小说,需要的朋友可以修改一下抓取其它数据。

利用curl和正则表达式做的一个针对磨铁中文网非vip章节的小说抓取器,支持输入小说ID下载小说。

依赖项:curl

可以简单的看下,里面用到了curl ,正则表达式,ajax等技术,适合新手看看。在本地测试,必须保证联网并且确保php开启curl的mode

SpiderTools.class.php 代码如下:

  1. <?php
  2. session_start();
  3. //封装成类 开启这些自动抓取文章
  4. #header("Refresh:30;http://www.test.com:8080");
  5. class SpiderTools{
  6. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  7. /*传入文章ID 解析出文章标题*/
  8. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. public function getBookNameById($aid){
  10. //初始化curl
  11. $ch= curl_init();
  12. //url
  13. $url='http://www.motie.com/book/'.$aid;
  14. if(is_numeric($aid)){
  15. //正则表达式匹配
  16. $ru="/<h1\sclass=\"p-title\">\s*<a\shref=\"\/book\/\d+\">(.*)\s*<\/a>\s*<\/h1>/";
  17. }
  18. else{
  19. //<title>丧尸爆发之全家求生路_第一章 丧尸爆发  为吾友爱乐儿更新~_磨铁</title>
  20. $ru="/<title>(.*)<\/title>/";
  21. }
  22. //设置选项,包括URL
  23. curl_setopt($ch, CURLOPT_URL, $url);
  24. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//不自动输出内容
  25. curl_setopt($ch, CURLOPT_HEADER, 0);//不返回头部信息
  26. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 0);
  27. //执行curl
  28. $output = curl_exec($ch);
  29. //错误提示
  30. if(curl_exec($ch) === false){
  31. die(curl_error($ch));
  32. }
  33. // 检查是否有错误发生
  34. if(curl_errno($ch)){
  35. echo 'Curl error: ' . curl_error($ch);
  36. }
  37. //释放curl句柄
  38. curl_close($ch);
  39. $arr=array();
  40. preg_match_all($ru,$output,$arr);
  41. return $arr[1][0];
  42. }
  43. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  44. /*传入文章ID 解析文章内容*/
  45. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  46. public function getBookContextById($aid){
  47. //开始解析文章
  48. $ids=array();
  49. $ids=explode("_",$aid);
  50. $titleId=trim($ids[0]);
  51. $aticleId=trim($ids[1]);
  52. $ch= curl_init();
  53. $ru="/<div class=\"page-content\">[\s\S]*<pre ondragstart=\"return false\" oncopy=\"return false;\" oncut=\"return false;\" oncontextmenu=\"return false\" class=\"note\" html_content_\d*\">[\s\S]*(.*)<img src=\"\/ajax\/chapter\/$titleId\/$aticleId\" class=\"hidden\" \/><\/pre>/ui";
  54. $url='http://www.motie.com/book/'.$aid;
  55. //正则表达式匹配
  56. //设置选项,包括URL
  57. curl_setopt($ch, CURLOPT_URL, $url);
  58. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//不自动输出内容
  59. curl_setopt($ch, CURLOPT_HEADER, 0);//不返回头部信息
  60. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 0);
  61. //执行curl
  62. $output = curl_exec($ch);
  63. //错误提示
  64. if(curl_exec($ch) === false){
  65. die(curl_error($ch));
  66. }
  67. // 检查是否有错误发生
  68. if(curl_errno($ch)){
  69. echo 'Curl error: ' . curl_error($ch);
  70. }
  71. $arr=array();
  72. $arr2=array();
  73. preg_match_all($ru,$output,$arr);
  74. curl_close($ch);
  75. #var_dump($arr);
  76. $s=$arr[0][0];
  77. $s=substr($s,180);
  78. $arr2=explode("<img",$s);
  79. return trim($arr2[0]);
  80. }
  81. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  82. /*静态方法 @生成小说文件 可以直接调用 */
  83. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  84. public static function createBookById($id){
  85. if(!is_numeric($id)){
  86. echo "<br/>INIT BEGIN START WRITE!";
  87. $st=new self();
  88. $cons=$st->getBookContextById($id);
  89. $title=$st->getBookNameById($id);
  90. $cons=trim($cons);
  91. $t=explode(" ",$title);
  92. //构造目录
  93. $dir=array();
  94. $dir=explode("_",$t[0]);
  95. $wzdir=$dir[0]; //书名称 作为目录名称
  96. $wzchapter=$dir[1]; //第几章
  97. //创建目录
  98. $wzdir2=iconv("UTF-8", "GBK", $wzdir);//目录编码 注意这里保留对$wzdir字符串的引用,用来构造文件名,不能用此处,防止二次编码
  99. if(!file_exists($wzdir2)){
  100. mkdir($wzdir2); //创建目录
  101. }
  102. //构造文件名
  103. $wztitle="./".$wzdir."/"."$t[0]".".txt";
  104. //保证保存的文件名称不是乱码
  105. $wztitle=iconv("UTF-8", "GBK", $wztitle);
  106. $f=fopen($wztitle,"w+");
  107. fwrite($f,$cons);
  108. echo "<font color='green'>$wzdir </font>".$wzchapter."<font color='red'>写入成功</font>";
  109. fclose($f);
  110. }
  111. else{
  112. $ids=self::getBookIdsById($id);
  113. //这里服务器可能会掉线,所以最好用session记录循环
  114. #for($i=$_SESSION["$id"."_fid"];$i<=count($ids);$_SESSION["$id"."_fid"]++,$i++){
  115. #self::createBookById($id."_".$ids[$_SESSION["$id"."_fid"]++]);//构造id
  116. #}
  117. for($i=$_SESSION["$id"."_fid"];$i<=count($ids);$_SESSION["$id"."_fid"]++,$i++){
  118. self::createBookById($id."_".$ids[$i]);//构造id
  119. }
  120. #echo "<hr/><hr/><br/><h1>写入工作全部完成</h1>";
  121. #echo $id."_".$ids[0]."<br/>";
  122. #var_dump($ids);
  123. }
  124. }
  125. /*
  126. 获取小说的所有ID
  127. @param $id 文章ID
  128. @return array;
  129. */
  130. public static function getBookIdsById($aid){
  131. $ch= curl_init();
  132. $url='http://www.motie.com/book/'.$aid."/chapter";
  133. //注意这里的?可以获取最少匹配项
  134. $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';//正则表达式匹配
  135. //设置选项,包括URL
  136. curl_setopt($ch, CURLOPT_URL, $url);
  137. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//不自动输出内容
  138. curl_setopt($ch, CURLOPT_HEADER, 0);//不返回头部信息
  139. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 0);
  140. //执行curl
  141. $output = curl_exec($ch);
  142. // 检查是否有错误发生
  143. if(curl_errno($ch)){
  144. echo 'Curl error: ' . curl_error($ch);
  145. }
  146. //释放curl句柄
  147. curl_close($ch);
  148. $arr=array();
  149. preg_match_all($ru,$output,$arr,PREG_PATTERN_ORDER);
  150. return $arr[1];
  151. }
  152. }
  153. ?>

getinfo.php 代码如下:

  1. <?php
  2. session_start();
  3. require_once("SpiderTools.class.php");
  4. if($_REQUEST["bid"]){
  5. if(is_numeric($_REQUEST["bid"])){
  6. SpiderTools::createBookById(trim($_REQUEST["bid"]));
  7. }
  8. else{
  9. echo "<br/>请输入正确的文章ID<br/>";
  10. }
  11. }
  12. ?>

index.html 代码如下:

  1. <html>
  2. <head><meta charset="utf-8"/></head>
  3. <title>下载小说啦</title>
  4. <body>
  5. <h1>输入磨铁中文网你想看到的小说ID号就可以下载小说啦</h1>
  6. <form method="get" action="getinfo.php">
  7. <input type="text" name="myid" value=""/>
  8. <input type="button" value="生成小说" onclick="createbook();"/>
  9. </form>
  10. <div >
  11. </div>
  12. <!-----AJAX------>
  13. <script language="javascript">
  14. var xmlHttp;
  15. function createbook()
  16. {
  17. xmlHttp=GetXmlHttpObject()
  18. if (xmlHttp==null)
  19. {
  20. alert ("浏览器不支持ajax")
  21. return
  22. }
  23. var bookmyid").value
  24. var url="getinfo.php"
  25. url=url+"?bid="+bookid;
  26. url=url+"&sid="+Math.random()
  27. xmlHttp.onreadystatechange=stateChanged
  28. xmlHttp.open("GET",url,true)
  29. xmlHttp.send(null)
  30. }
  31. function stateChanged()
  32. {
  33. if(xmlHttp.readyState==1){
  34. document.getElementById("info").innerHTML="正在准备工作,请耐心点哦~^_^~<img src=\"img/1.gif\" /><br/>";
  35. }
  36. if(xmlHttp.readyState==2){
  37. document.getElementById("info").innerHTML="正在联系服务器,这可能需要一点时间啦^><img src=\"img/2.gif\" /><^<br/>";
  38. }
  39. if(xmlHttp.readyState==3){
  40. document.getElementById("info").innerHTML="正在解析数据<img src=\"img/3.gif\" /><br/>";
  41. }
  42. if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
  43. {
  44. document.getElementById("info").innerHTML=xmlHttp.responseText;
  45. //xmlHttp.abort();
  46. }
  47. }
  48. function GetXmlHttpObject()
  49. {
  50. var xmlHttp=null;
  51. try
  52. {
  53. // Firefox, Opera 8.0+, Safari
  54. xmlHttp=new XMLHttpRequest();
  55. }
  56. catch (e)
  57. {
  58. //Internet Explorer
  59. try
  60. {
  61. xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
  62. }
  63. catch (e)
  64. {
  65. xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
  66. }
  67. }
  68. return xmlHttp;
  69. }
  70. </script>
  71. </body>
  72. </html>