1445字

本文由 简悦 SimpRead 转码, 原文地址 blog.mjyai.com

官方文档简洁清晰,再增加内容就显得臃肿了。故另外写一篇对新手友好的指南。

发表于 2021-01-31|更新于 2022-10-22|笔记

| 阅读量:

官方文档简洁清晰,再增加内容就显得臃肿了。故另外写一篇对新手友好的指南。

万物皆可 RSS,这个项目是一个将任意网页内容转换为 RSS 的框架。其开源性质其实是鼓励大家按个人需求自己动手写规则的。

有的网站是有提供 RSS 的,如果你只是需要全文输出可以结合 full-text-rss 来实现。
有的网站已经有 RSSHub 规则了,可以通过 RSSHub RadarRSSBud 快速发现和订阅。

Fork 然后将你的项目git clone到本地。
给你的项目增加上游:

git remote add upstream https://github.com/DIYgod/RSSHub

若以前已贡献过则需要从上游获取最新内容并强制更新:

git fetch upstream
git reset --hard upstream/master
git rebase upstream/master
git push -f origin master

推荐用 Node Version Manager 灵活切换 npm 版本。

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash

重启终端然后安装 npm 的稳定版:

nvm install stable

国内环境则推荐改为淘宝源(可选):

npm config set registry https://registry.npm.taobao.org

通过npm config get registry可检查是否更改成功。

进入项目根目录。

npm install
npm run dev

然后浏览器打开http://localhost:1200dev模式下每次保存项目就会自动重启应用修改,方便实时调试。

这里以网易号(通用)为例解释如何添加新规则。
网易对大部分网易号是提供了 api 调取文章列表的,但有些网易号搜索页面搜不到的小众网易号(文章页面不含data-wemediaid)无法用 api 获取网页列表。
比如这个后厂村体工队

添加脚本路由

打开/lib/router.js,增加路由。

router.get('/netease/dy2/:id', require('./routes/netease/dy2'));

由前面网易号的主页可见,其链接最后 html 的文件名可用于区分网易号,故作为参数id传入脚本。若是可选参数则是:param?这样的格式。

编写脚本

/lib/routes/中的路由对应路径下创建新的 js 脚本。由前面路由可见新建dy2.js

import 所需模块

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

这里got用来获取 html 信息,cheerio处理获取的数据。由于某些网易页面并不是用通用的utf8编码,故还需要iconv-lite进行格式转换。

获取主页数据并生成文章列表

优先用 api 方式获取,但由前所述此法不可行。故直接抓取主页信息。另外还有一种方法是使用puppeteer渲染页面,这里不涉及。

const id = ctx.params.id;

const url = `https://www.163.com/dy/media/${id}.html`;

const response = await got.get(url, { responseType: 'buffer' });

const data = iconv.decode(response.data, 'gbk');

const $ = cheerio.load(data, { decodeEntities: false });


const list = $('.media_articles ul li')
    
    .slice(0, 5)
    
    .map((_, item) => {
        item = $(item);
        
        const a = item.find('h2.media_article_title a');
        
        let pubDate = item.find('.media_article_date').text();
        pubDate = new Date(pubDate).toUTCString();
        
        return {
            title: a.text(),
            link: a.attr('href'),
            pubDate: pubDate,
        };
    })
    .get();

具体如何用浏览器选择可见这节图文教程

遍历文章列表并抓取全文

const items = await Promise.all(
    list.map(async (item) => {
        let content;
        
        if (item.link.startsWith('https://www.163.com')) {
            
            const itemData = await ctx.cache.tryGet(item.link, async () =>
                iconv.decode(
                    (
                        await got.get(item.link, {
                            responseType: 'buffer',
                        })
                    ).data,
                    'gbk'
                )
            );
            content = cheerio.load(itemData, { decodeEntities: false });
        
        } else {
            const itemData = await ctx.cache.tryGet(
                item.link,
                async () =>
                    (
                        await got.get(item.link, {
                            responseType: 'buffer',
                        })
                    ).data
            );
            content = cheerio.load(itemData, { decodeEntities: false });
        }

        
        const eDescription = content('.post_body').html();

        
        const single = {
            title: item.title,
            link: item.link,
            description: eDescription,
            pubDate: item.pubDate,
        };
        return Promise.resolve(single);
    })
);

注:网易原来有部分网址是 gbk 编码的,现在全部改成 utf-8 了,处理更方便。更新代码见此处

let link;
ctx.state.data = {
    title: $('.media_info h1').text(),
    link,
    description: '',
    item: items,
};

添加脚本文档

更新/docs/目录内对应的文档,可以执行npm run docs:dev查看文档效果。
这里网易号属于新媒体,故修改/docs/new-media.md

## 网易号(通用)
<Route author="mjysci" example="/netease/dy2/T1555591616739" path="/netease/dy2/:id" :paramsDesc="['id,该网易号主页网址最后一项html的文件名']" anticrawler="1"/> 
优先使用方法一,若是网易号搜索页面搜不到的小众网易号(文章页面不含`data-wemediaid`)则可使用此法。
触发反爬会只抓取到标题,建议自建。

格式是markdown。其中:paramsDesc是通过数组解释路由中每个参数的作用和获取方式,其他项不言自明,参考这个例子填写即可。

第三方 RSSHub,对于反爬严格的网站还是推荐自建服务

提交新的 RSSHub 规则
RSSHub 文档