发现写满了注释就没啥好说的了,姑且称为教程吧。
需要自己操作的核心只是$regex_item和$regex_item2这两个正则的修改。如有兴趣,可另开教程。
聪明的你可能会发现这两个匹配的内容不是一样的吗,那为什么不合二为一呢?
RSS全文订阅
这里以PHP版为例,尽量说得通俗点吧,水平实在有限,见谅。虽然并没有多高深,但请转载者注意起码的礼貌。
目前我这里所有的获取全文输出的网站大概是三种情况:
第一种最省事,第二种最常见,第三种稍麻烦。
今天先讲第二种。
以知乎日报为例 (链接),先看代码:(把下列源码存为zhihu.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php include "gethtml.php"; $regex_link = '/(?<=<a href="\/story\/).+?(?=")/'; $regex_tit = '/(?<=<title>)(.+?)(?= -)/s'; $regex_con = '/<span class="img-source">.*?(?=<div class="qr">)/s'; $header = '<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>知乎日报</title>'; $footer = '</channel></rss>'; $html = gethtml('http://daily.zhihu.com/'); if (preg_match_all($regex_link, $html, $links)) { foreach($links[0] as $link) { $link = preg_replace('/(.+)/','http://daily.zhihu.com/story/$1', $link); $content = gethtml($link); preg_match($regex_con, $content, $article); preg_match($regex_tit, $content, $title); $rss.= '<item><title>'.$title[0].'</title><link><![CDATA['.$link. ']]></link><description><![CDATA['.$article[0].']]></description></item>'; } file_put_contents('zhihu.xml',$header.$rss.$footer); } ?> |
重点是第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.site/rss/tutorial/zhihuu.php,只要程序不出错,就会同目录生成zhihu.xml,订阅地址即为https://feedx.site/rss/tutorial/zhihu.xml
怎么自动打开那个网址呢,crontab、计划任务、cPanel、wordpress插件都可以,如果都没有的话,网上也是有人提供这个服务的,http://cron-job.org,自己去看吧…
上面我说的查找、挑出都是用正则来实现的,此外最好对html特别熟悉,操作起来才能得心应手。
想要自己完成还是要有一定基础的,完全靠伸手是不现实的,还不如去买那些能可视化操作的产品。如果正则不熟或不想学,可以试试PHP Simple HTML DOM Parser,类似jQuery。
============================================
参数的用法:
默认可以不加参数,基本写法是这样的:
1 2 3 4 |
$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']; $args=['headers'=>$headers,'header'=>1]; $url='http://feedx.site'; $html=gethtml($url,$args); |
上面的意思是我去抓取的时候让自己更像个浏览器,模拟的是chrome 65.0.3325.162版,还加上了cookie;因为一个网址可能会跳转很多次才到目标网址,通常我们是不用去管这些的,比如我好奇心很重,就可以把header信息也打印出来。还有更多的一些用法可以参考curl自己添加。
============================================
下面是在别人的基础上自己总结的利用curl抓取页面的方法,把下面源码存为gethtml.php,与zhihu.php放于同一目录下。我所有的抓取都是用的这个方法,当然,省事的话可以用 file_get_contents,那就是真正的20行代码完成全文RSS输出了,不过可选的参数就没有了,有的页面会抓取不到。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<?php function gethtml($url,$args=null){ $proxy = $args["proxy"]?$args["proxy"]:''; $headers = $args["headers"]?$args["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']; $nobody = $args["nobody"]?$args["nobody"]:0; $header = $args["header"]?$args["header"]:0; $ch = curl_init(); $options = array( CURLOPT_URL => @$url, CURLOPT_PROXY => @$proxy, CURLOPT_HTTPHEADER => @$headers, CURLOPT_NOSIGNAL => 1, CURLOPT_HEADER => @$header, CURLOPT_NOBODY => @$nobody, CURLOPT_RETURNTRANSFER => 1, CURLOPT_FOLLOWLOCATION => 1 ); if (preg_match('/^https/',$url)){ $options[CURLOPT_SSL_VERIFYHOST] = 2; $options[CURLOPT_SSL_VERIFYPEER] = 0; } curl_setopt_array($ch, $options); $data = curl_exec($ch); $curl_errno = curl_errno($ch); curl_close($ch); if($curl_errno>0){ return 'error'; }else{ return $data; } } ?> |