当前位置:首页 > PHP教程 > php应用 > 列表

php程序员还看带广告的小说?

发布:smiling 来源: PHP粉丝网  添加日期:2022-06-13 08:39:24 浏览: 评论:0 

有人习惯看小说,偶尔会看几章,都是百度出来,但是基本都有特别烦人的广告,要么在整体div添加链接,误触就会跳转到一些网站甚至是死循环,某些手机app也是广告很多,所以无事在写一个小程序免除广告的烦扰。

本文将使用php curl采集页面simple_html_dom解析,实现真正的去除广告。

随便找一个小说网站找一本书,不过这个站点在手机端是特别坑的,就有上述问题:

程序员还看带广告的小说?

就拿这本小说来开刀。(声明:绝对不是推广,侵删)

一、了解curl的get方式

curl是一个命令行工具,通过指定的URL来上传或下载数据,并将数据展示出来。curl中的c表示client,而URL,就是URL。

PHP中使用cURL可以实现Get和Post请求的方法

简单的抓取小说仅需要get方法即可。

下面这个示例代码就是通过get请求获取第一章小说页面html的示例,只需要更改url参数即可。

初始化、设置选项、证书验证、执行、关闭

  1. <?php 
  2.  
  3. header("Content-Type:text/html;charset=utf-8"); 
  4.  
  5. $url="https://www.7kzw.com/85/85445/27248636.html"
  6.  
  7. $ch = curl_init($url);   //初始化 
  8.  
  9. //设置选项 
  10.  
  11. curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//获取的信息以字符串返回,而不是直接输出(必须)  
  12.  
  13. curl_setopt($ch,CURLOPT_TIMEOUT,10);//超时时间(必须) 
  14.  
  15. curl_setopt($ch, CURLOPT_HEADER,0);//   启用时会将头文件的信息作为数据流输出。  
  16.  
  17. //参数为1表示输出信息头,为0表示不输出 
  18.  
  19. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); //不验证证书 
  20.  
  21. // 3.执行 
  22.  
  23. $res = curl_exec($ch); 
  24.  
  25. // 4.关闭 
  26.  
  27. curl_close($ch); 
  28.  
  29. print_r($res); 
  30.  
  31. ?> 

注释就特别详细了,按照步骤,发送curl的get请求,如果是post请求则需要多加一条设置post选项的设置,并且传参,最后输出获得的信息,运行结果如下,是没有css渲染的。

程序员还看带广告的小说?

二、解析页面

输出的页面有很多不需要的内容,需要在所有内容中提取出我们需要的内容,比如标题和每章的内容,这时需要解析页面。

解析页面的方法也有很多,在这里使用的是simple_html_dom,需要下载引用simple_html_dom.php这个类,实例对象,并调用内部的方法。具体方法可以到官网查看,或者中文网其他文档。

先分析这个小说页面的源代码,看这章的标题和内容对应的元素

首先是标题:在类bookname下的h1下

程序员还看带广告的小说?

然后是内容:在id为content的div下

程序员还看带广告的小说?

simple_html_dom的可以使用find方法,类似jquery一样使用选择器查找定位元素。如:

find('.bookname h1'); //查找类bookname 下的h1标题元素

find('#content'); //查找id为content的章节内容

代码在以上的基础上新增:

  1. include "simple_html_dom.php"
  2.  
  3. $html = new simple_html_dom(); 
  4.  
  5. @$html->load($res); 
  6.  
  7. $h1 = $html->find('.bookname h1'); 
  8.  
  9. foreach ($h1 as $k=>$v) { 
  10.  
  11.     $artic['title'] = $v->innertext; 
  12.  
  13.  
  14. // 查找小说的具体内容 
  15.  
  16. $divs = $html->find('#content'); 
  17.  
  18. foreach ($divs as $k=>$v) { 
  19.  
  20.     $content = $v->innertext; 
  21.  
  22.  
  23. // 正则替换去除多余部分 
  24.  
  25. $pattern = "/(<p>.*?<\/p>)|(<div .*?>.*?<\/div>)/"
  26.  
  27. $artic['content'] = preg_replace($pattern,'',$content); 
  28.  
  29. echo $artic['title'].'<br>'
  30.  
  31. echo $artic['content']; 

使用以上的解析方法获得的内容是数组,使用foreach来获得数组内容,使用了正则替换将正文文字广告去除,将标题和小说内容放到数组内。最简单的写法就写好了,运行结果如下:

程序员还看带广告的小说?

当然这种写法看着比较难受,可以自行封装函数类,如下就是我自己写好的代码示例了,当然肯定有不足的地方,但是可以作为参考扩展。

  1. <?php  
  2.  
  3. include "simple_html_dom.php"
  4.  
  5. include "mySpClass.php"
  6.  
  7. header("Content-Type:text/html;charset=utf-8"); 
  8.  
  9. $get_html = get_html($_GET['n']); 
  10.  
  11. $artic = getContent($get_html); 
  12.  
  13. echo $artic['title'].'<br>'
  14.  
  15. echo $artic['content']; 
  16.  
  17. /** 
  18.  
  19. * 获取www.7kzw.com 获取每一章的页面html 
  20.  
  21. * @param type $num 第几章,从第一开始(int) 
  22.  
  23. * @return 返回字符串   
  24.  
  25. */ 
  26.  
  27. function get_html($num){ 
  28.  
  29.     $start = 27248636; 
  30.  
  31.     $real_num = $num+$start-1; 
  32.  
  33.     $url = 'https://www.7kzw.com/85/85445/'.$real_num.'.html'
  34.  
  35.     $header = [ 
  36.  
  37.     'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0' 
  38.  
  39.     ];  
  40.  
  41.     return mySpClass()->getCurl($url,$header); 
  42.  
  43.  
  44. /** 
  45.  
  46. * 获取www.7kzw.com小说标题数组 
  47.  
  48. * @param type $get_html 得到的每一章的页面html 
  49.  
  50. * @return 返回$artic数组,['title'=>'','content'=>''] 
  51.  
  52. */ 
  53.  
  54. function getContent($get_html){ 
  55.  
  56.     $html = new simple_html_dom(); 
  57.  
  58.     @$html->load($get_html); 
  59.  
  60.     $h1 = $html->find('.bookname h1'); 
  61.  
  62.     foreach ($h1 as $k=>$v) { 
  63.  
  64.         $artic['title'] = $v->innertext; 
  65.  
  66.     } 
  67.  
  68.     // 查找小说的具体内容 
  69.  
  70.     $divs = $html->find('#content'); 
  71.  
  72.     foreach ($divs as $k=>$v) { 
  73.  
  74.         $content = $v->innertext; 
  75.  
  76.     } 
  77.  
  78.     // 正则替换去除多余部分 
  79.  
  80.     $pattern = "/(<p>.*?<\/p>)|(<div .*?>.*?<\/div>)/"
  81.  
  82.     $artic['content'] = preg_replace($pattern,'',$content); 
  83.  
  84.     return $artic
  85.  
  86.  
  87. ?> 
  88.  
  89.  
  90. <?php 
  91.  
  92. class mySpClass{ 
  93.  
  94.     //单例对象 
  95.  
  96.     private static $ins = null; 
  97.  
  98.     /** 
  99.  
  100.      * 单例化对象 
  101.  
  102.      */ 
  103.  
  104.     public static function exec() 
  105.  
  106.     { 
  107.  
  108.         if (self::$ins) { 
  109.  
  110.             return self::$ins
  111.  
  112.         } 
  113.  
  114.         return self::$ins = new self(); 
  115.  
  116.     } 
  117.  
  118.       
  119.  
  120.     /** 
  121.  
  122.      * 禁止克隆对象 
  123.  
  124.      */ 
  125.  
  126.     public function __clone() 
  127.  
  128.     { 
  129.  
  130.         throw new curlException('错误:不能克隆对象'); 
  131.  
  132.     } 
  133.  
  134.     // 向服务器发送最简单的get请求 
  135.  
  136.     public static function getCurl($url,$header){ 
  137.  
  138.         // 1.初始化 
  139.  
  140.         $ch = curl_init($url);   //请求的地址 
  141.  
  142.         // 2.设置选项 
  143.  
  144.         curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//获取的信息以字符串返回,而不是直接输出(必须)  
  145.  
  146.         curl_setopt($ch,CURLOPT_TIMEOUT,10);//超时时间(必须) 
  147.  
  148.         curl_setopt($ch, CURLOPT_HEADER,0);//   启用时会将头文件的信息作为数据流输出。  
  149.  
  150.         //参数为1表示输出信息头,为0表示不输出 
  151.  
  152.         curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); //不验证证书 
  153.  
  154.         curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); //不验证证书 
  155.  
  156.         if(!emptyempty($header)){ 
  157.  
  158.             curl_setopt($ch,CURLOPT_HTTPHEADER,$header);//设置头信息 
  159.  
  160.         } 
  161.  
  162.         // 3.执行 
  163.  
  164.         $res = curl_exec($ch); 
  165.  
  166.         // 4.关闭 
  167.  
  168.         curl_close($ch); 
  169.  
  170.         return $res
  171.  
  172.     } 
  173.  
  174.  
  175. //curl方法不存在就设置一个curl方法 
  176.  
  177. if (!function_exists('mySpClass')) { 
  178.  
  179.     function mySpClass() { 
  180.  
  181.         return mySpClass::exec(); 
  182.  
  183.     } 
  184.  
  185.  
  186. ?> 

以上示例代码的最终运行结果:第几章就输入数字几,通过$_GET['n']传参

程序员还看带广告的小说?

总结:

知识点:curl(tips:curl模块采集任意网页php类),正则,解析工具simple_html_dom

虽然写法已经初步完善,但是最好能过部署的自己的服务器才能有最好的效果,不然只能在电脑观看,也不见得多方便,可能更愿意忍忍广告了。

Tags: php程序员 带广告小说

分享到: