自定义RSSHub订阅学校官网,一劳永逸


疫情初期,阿里云赠送在校大学生免费使用一年2G2H云服务器,想着不能浪费了,能不能在上边搭一些服务玩一玩。自己对信息的获取也是比较重视的,很早就在用RSS,这种订阅方式很高效,订阅自己关注的几个博客就可以,与之对应的是,微博、微信、知乎这些地方的信息量太大了,看一会很容易造成递归,然后,我的时间就被偷走了!

最初的构想是搭建一个RSS服务器,然后用feed43自定义功能,制作几个feed链接,但是feed43的爬取速度太慢了,要很长时间才能更新,不利于信息的及时获取,就继续寻找,找到了一个开源项目,也就是今天的主角RSSHub。

@> 万物皆可 RSS

@> RSSHub 是一个开源、简单易用、易于扩展的 RSS 生成器,可以给任何奇奇怪怪的内容生成 RSS 订阅源。RSSHub 借助于开源社区的力量快速发展中,目前已适配数百家网站的上千项内容。

敢打出“万物皆可RSS”的口号,说明还是很有实力的,实际体验下来也确实,路由众多,开源,用户可以随意扩展。

回到最本源,目的很单纯,找寻一个可靠的方式,订阅学校官网信息,这样就不用在需要自己去官网看消息了,有什么消息RSS会自动通知我,根据兴趣确定是否要进去官网看,省时省力!

(时间:2020年4月)看了一眼官网的文档,这好像什么都写了,也好像什么也没写,对于没有前端基础的我来说,这些都是问题!于是,放弃!

时间回到现在,这次发现了TG可以订阅RSS,又有了重启RSSHub的想法,于是又开始硬着头皮看文档,有一说一,文档写的非常“垃圾”(bushi。我没有一点前端基础,这玩意根本看不懂啊,去网上找博客,竟然没找到,也可能是我的搜索姿势有问题。

什么是PR啊?

看了其他人的pr,好像有了些门路,好像只需要修改一下仓库的js文件就好了!真的吗?真的这么简单吗?

那么问题来了,天天听人家说pr,我还从来没提交过pr呢。

不管了,这仓库我并没有操作权限,先fork一波,clone到本地再说!

安装依赖

奇妙的事情发生了,按照文档操作,npm install一波依赖后,进入http://localhost:1200,已经出现了一些东西了,这条路应该没错。

安装依赖的时候,由于网络原因和一些看不懂的原因,出现了一些报错,这也为之后埋下了坑。

写(chao)路由和脚本

尝试原封不动偷(不对,读书人的事情,怎么能是偷呢,这是学习!)其他学校的路由、脚本,改成自己学校的路径,对应页面,哇,真的可以啊!

真的是so easy呢!

马上看代码,想着怎么怎么修改一下,这不就完了吗!

(草,一种植物)高兴得太早了,触及到我的知识盲区了,我没学过爬虫,也不会js,这可咋整,咱啥也不会,copy还是有一手的,然后找了几十家学校,最终敲定了zju的代码。

经过机智的我努力的修改,很快就搞定了!(屁,你明明对着代码改了有大几个小时!)

改这个很简单的,只需要这样那样然后再这样就好了!(人言否?

实际上,我对着人家的官网的HTML代码和我们学校官网的HTML代码看了半天,终于发现这个.lists tr好像有点东西,他们都是class=”xxx”格式的,搜一下,看看我这有没有,果然,牛逼啊!然后又改了几个地方,算是改出来了。这部分一句两句是说不清楚的,因为我没有这个基础,所以只能一边搜,一边比对代码,虽然花了大量时间,结果还好。

campus/index.js

const got = require('@/utils/got');
const cheerio = require('cheerio');

const map = new Map([
    [0, { title: '公告信息', link: 'http://info.zzuli.edu.cn/_t961/2464/list.htm' }],
    [1, { title: '学工信息', link: 'http://info.zzuli.edu.cn/_t961/xsxx/list.htm' }],
    [2, { title: '教学信息', link: 'http://info.zzuli.edu.cn/_t961/jwxx/list.htm' }],
    [3, { title: '信息快递', link: 'http://info.zzuli.edu.cn/_t961/2536/list.htm' }],
    [4, { title: '学术报告', link: 'http://info.zzuli.edu.cn/_t961/xsbg/list.htm' }],
    [5, { title: '科研信息', link: 'http://info.zzuli.edu.cn/_t961/kyxx/list.htm' }],
    [6, { title: '网络公告', link: 'http://info.zzuli.edu.cn/_s19/_t960/wlgg/list.psp' }],
    [7, { title: '班车查询', link: 'http://info.zzuli.edu.cn/_s19/_t960/2619/list.htm' }],
    [8, { title: '周会表', link: 'http://info.zzuli.edu.cn/_s19/_t960/bzhy/list.psp' }],
]);

module.exports = async (ctx) => {
    const type = Number.parseInt(ctx.params.type);
    const id = map.get(type).link;
    const res = await got({
        method: 'get',
        url: `${id}`,
        responseType: 'buffer',
    });

    const $ = cheerio.load(res.data);
    const list = $('.lists tr').slice(0, 10);
    const items =
        list &&
        list
            .map((index, item) => {
                item = $(item);
                return {
                    title: item.find('td a').attr('title'),
                    link: item.find('td a').attr('href'),
                    pubDate: new Date(item.find('td div').text()),
                };
            })
            .get();

    ctx.state.data = {
        title: map.get(type).title+' - 郑州轻工业大学智慧门户',
        link: map.get(type).link,
        item: items,
    };
};

接着又搞了一个研究生处的RSS。

这个和前边的很不一样,看到这研究生处官网的HTML代码,我开始怀疑这个人的能力了!怎么和前边不一样啊,class让你吃了吗?别人官网都有class这个的,你没有我怎么玩啊?

那好吧,我又开始了我的传统艺能,看看人家是怎么写的吧,通过学习,好像也发现了点东西。

const list = $('div table tbody tr td table tbody tr').slice(0, 10);

这句话看样子是把这个HTML的结构给表示出来了,于是对着修改成了现在的样子。

运行后,卧槽!牛逼啊!不愧是我!

至此,研究生处的RSS也就出生了。(当然,也咨询了爬虫大佬栋哥@kiedeng,栋哥说用正则搞一下,凭借着正则的思想,我才发现了这段灵魂代码,感谢栋哥。)

zzuli/yjsc/index.js

const got = require('@/utils/got');
const cheerio = require('cheerio');

const map = new Map([
    [0, { title: '公告通知', link: 'http://yjsc.zzuli.edu.cn/ggtz/list.htm' }],
    [1, { title: '招生工作', link: 'http://yjsc.zzuli.edu.cn/2878/list.htm' }],
    [2, { title: '新闻资讯', link: 'http://yjsc.zzuli.edu.cn/2918/list.htm' }],
    [3, { title: '培养工作', link: 'http://yjsc.zzuli.edu.cn/2882/list.htm' }],
    [4, { title: '学位工作', link: 'http://yjsc.zzuli.edu.cn/2890/list.htm' }],
]);

module.exports = async (ctx) => {
    const type = Number.parseInt(ctx.params.type);
    const id = map.get(type).link;
    const res = await got({
        method: 'get',
        url: `${id}`,
        responseType: 'buffer',
    });

    const $ = cheerio.load(res.data);
    const list = $('div table tbody tr td table tbody tr').slice(0, 10);
    const items =
        list &&
        list
            .map((index, item) => {
                item = $(item);
                return {
                    title: item.find('td a').attr('title'),
                    link: item.find('td a').attr('href'),
                    pubDate: new Date(item.find('td div').text()),
                };
            })
            .get();

    ctx.state.data = {
        title: map.get(type).title+' - 郑州轻工业大学研究生处',
        link: map.get(type).link,
        item: items,
    };
};

添加脚本文档

这部分说白了就是在文档中显示这个rss,帮助其他人使用,按照教程的操作,npm run docs:dev,好了,我运行了,但是,他报错了!这也是之前安装依赖的时候出现的错误没有注意,还好没影响我调试脚本。搞了半天,也检查了网络问题,用了淘宝源,能用的方法都用了,还是安装不成功。我投降!

好在这部分只需要按照格式写一下markdown就可以了。

所以,pr到底是啥?

pull request,简称PR。

确认我只在本地修改了4个文件(增加了两个,修改了两个)后,运行命令git add命令

git add .\lib\routes\universities\zzuli\campus\index.js .\lib\routes\universities\zzuli\yjsc\index.js .\lib\router.js .\docs\university.md

然后git status一波看结果。

PS F:\DESK\rsshub\RSSHub> git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   docs/university.md
        modified:   lib/router.js
        new file:   lib/routes/universities/zzuli/campus/index.js
        new file:   lib/routes/universities/zzuli/yjsc/index.js

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)

        modified:   package.json

Untracked files:

        lib/routes/universities/zzuli/ggtz.js

我好想还有些残局没有收拾,忘记删除最开始的调试脚本,ggtz.js,还有一个文件进行了修改,并没有add它。

  • 删除ggtz.js del ggtz.js当然,linux是rm -rf ggtz.js
  • 撤销我的修改,git checkout .\package.json

开始commit

git commit -m "Add 郑州轻工业大学" -m "包括郑州轻工业大学 智慧门户:公告信息、学工信息、教学信息、信息快递、学术报告、科研信息、网络公告、班车查询、周会表;研究生处:公告通知、招生工作、新闻资讯、培养工作、学位工作"

这里说明一下,因为我想在pr中呈现出commit和description,我担心我只提供commit的话,对于其他人查看可能并不是很友好,于是搜了一下,第一个-m参数是commit,第二个-m参数是description部分。(事实证明,这好像没啥用,这个只是在本地的自己fork的仓库中呈现,pr的时候是有专门写描述的地方的。

最后就是git push了,第一次好像没有push成功,根据提示又pull,push了几次,算是成功了。

接下来就是终极问题,如何提交我的pr,在仓库中确确实实见到了我的commit,但是我怎样提交给原仓库呢?又是一波学习。

在自己仓库中点击Pull request,然后第一个选原站仓库,第二个选自己的仓库,点击下边的Create pull request,按照指示填一下信息,就可以了。

接下来就等自动bot测试pr等结果就好了,很顺利,一次通过。

image-20200722194015891

由于还没来得及更新doc,先使用人家提供的临时的preview。

使用的bot如图所示,很成功。

image-20200722194257122

在我快写好这篇博客的时候,两篇推送发来了,开心!

image-20200722194417714

另外,如果有iOS设备,就不需要全天挂梯子了,因为众所周知的原因,所有通知都是先发到Apple服务器,然后再发给手机的,所以就不需要科学上网,也能及时收到通知,这里给苹果点赞!安卓啥时候能这样啊!


文章作者: 卓木
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明来源 卓木 !
  目录