RSS 全文输出

这里以PHP版为例,尽量说得通俗点吧,水平实在有限,见谅。

目前我这里所有的获取全文输出的网站大概是三种情况:

  1. 要输出的内容集中在一页上,也就是看似列表页的页面里集中了你想要的所有内容,并不需要点击“更多”或“继续阅读”才能看到文章整体。比如糗事百科、wiki。
  2. 有列表页,要查看相应文章必须点击链接进入。
  3. json方式写入。特征就是查看源文件并不能找到你在浏览器中看到的内容。比如腾讯新闻图片(链接),它的真正内容在这(链接)。

第一种最省事,第二种最常见,第三种稍麻烦。

今天先讲第二种。

以知乎日报为例 (链接),先看代码:(把下列源码存为zhihu.php)

  1. <?php
  2. include “gethtml.php”;
  3. $regex_link = ‘/(?<=<a href=”\/story\/).+?(?=”)/’;
  4. $regex_tit = ‘/(?<=<title>)(.+?)(?= -)/s’;
  5. $regex_con = ‘/<span class=”img-source”>.*?(?=<div class=”qr”>)/s’;
  6. $header=‘<?xml version=”1.0″ encoding=”utf-8″?><rss version=”2.0″><channel><title>知乎日报</title>’;
  7. $footer=‘</channel></rss>’;
  8. $html=gethtml(‘http://daily.zhihu.com/’);
  9. if(preg_match_all($regex_link, $html, $links)){
  10. $size=count($links[0]);
  11. for($i=0;$i<$size;$i++){
  12. $link=preg_replace(‘/(.+)/’,‘http://daily.zhihu.com/story/$1’,$links[0][$i]);
  13. $content=gethtml($link);
  14. preg_match($regex_con,$content,$article);
  15. preg_match($regex_tit,$content,$title);
  16. $rss.=‘<item><title>’.$title[0].‘</title><link><![CDATA[‘.$link.‘]]></link><description><![CDATA[‘.$article[0].‘]]></description></item>’;
  17. }
  18. file_put_contents(‘zhihu.xml’,$header.$rss.$footer);
  19. }
  20. ?>

重点是第8行往后。只解释我认为重要的,不明白的可以讨论。

第2行,引入gethtml方法,来自下面的代码。

看一下第8行gethtml(‘http://daily.zhihu.com/’)得到了什么(链接),虽然有点乱,但是目的达到了,http://daily.zhihu.com/ 我已经抓到本地服务器上。

第9行是要挑出需要的链接 $links(链接

第13行利用这些链接继续抓取页面 $content=gethtml($link)

第14、15行从$content里查找需要的$title(文章标题)和$article(文章内容)

后面就是按RSS要求的格式输出,并最终生成xml文件。

最后,想办法打开https://feedx.net/rss/tutorial/zhihuu.php,只要程序不出错,就会同目录生成zhihu.xml,订阅地址即为https://feedx.net/rss/tutorial/zhihu.xml

怎么自动打开那个网址呢,crontab、计划任务、cPanel、wordpress插件都可以,如果都没有的话,网上也是有人提供这个服务的,http://cron-job.org,自己去看吧…

上面我说的查找、挑出都是用正则来实现的,此外最好对html特别熟悉,操作起来才能得心应手。

想要自己完成还是要有一定基础的,完全靠伸手是不现实的,还不如去买那些能可视化操作的产品。如果正则不熟或不想学,可以试试PHP Simple HTML DOM Parser,类似jQuery

============================================

参数的用法:

默认可以不加参数,基本写法是这样的:

  1. $headers=[‘User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36’,‘Cookie: BAIDUID=4C2D58EAE60F2ACDB32DCAAAA9795A4D:FG=1;H_WISE_SIDS=106370_122302; BDSVRTM=13’];
  2. $args=[‘headers’=>$headers,‘header’=>1];
  3. $url=‘http://feedx.net’;
  4. $html=gethtml($url,$args);

上面的意思是我去抓取的时候让自己更像个浏览器,模拟的是chrome 65.0.3325.162版,还加上了cookie;因为一个网址可能会跳转很多次才到目标网址,通常我们是不用去管这些的,比如我好奇心很重,就可以把header信息也打印出来。还有更多的一些用法可以参考curl自己添加。

============================================

下面是在别人的基础上自己总结的利用curl抓取页面的方法,把下面源码存为gethtml.php,与zhihu.php放于同一目录下。我所有的抓取都是用的这个方法,当然,省事的话可以用 file_get_contents,那就是真正的20行代码完成全文RSS输出了,不过可选的参数就没有了,有的页面会抓取不到。

  1. <?php
  2. function gethtml($url,$args=null){
  3. $proxy = $args[“proxy”]?$args[“proxy”]:;
  4. $headers = $args[“headers”]?$args[“headers”]:[];
  5. $nobody = $args[“nobody”]?$args[“nobody”]:0;
  6. $header = $args[“header”]?$args[“header”]:0;
  7. $ch = curl_init();
  8. $options = array(
  9. CURLOPT_URL => @$url,
  10. CURLOPT_PROXY => @$proxy,
  11. CURLOPT_HTTPHEADER => @$headers,
  12. CURLOPT_NOSIGNAL => 1,
  13. CURLOPT_HEADER => @$header,
  14. CURLOPT_NOBODY => @$nobody,
  15. CURLOPT_RETURNTRANSFER => 1,
  16. CURLOPT_FOLLOWLOCATION => 1
  17. );
  18. if (preg_match(‘/^https/’,$url)){
  19. $options[CURLOPT_SSL_VERIFYHOST] = 2;
  20. $options[CURLOPT_SSL_VERIFYPEER] = 0;
  21. }
  22. curl_setopt_array($ch, $options);
  23. $data = curl_exec($ch);
  24. $curl_errno = curl_errno($ch);
  25. curl_close($ch);
  26. if($curl_errno>0){
  27. return ‘error’;
  28. }else{
  29. return $data;
  30. }
  31. }
  32. ?>