mirror of
https://github.com/DIYgod/RSSHub.git
synced 2025-12-08 05:59:00 +08:00
feat(route): 微博自定义分组(使用Cookie) (#12514)
* change route 'weibo/user' to fit api could be opened with Share(third-party android weibo clent) * update weibo group route using cookies approach * fix typo * code optimization for /weibo/group; docs for /weibo/group * try fix ESLint error * fix typo and code optimization * fix missing ',' * '/weibo/group' throw error when the cookie is not set
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,6 +7,8 @@
|
||||
.vercel
|
||||
.vscode
|
||||
.yarn
|
||||
.yarnrc.yml
|
||||
.pnp*
|
||||
|
||||
*.swp
|
||||
*.iml
|
||||
|
||||
@@ -943,6 +943,14 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
|
||||
- `WEIBO_APP_SECRET`: 微博 App Secret
|
||||
- `WEIBO_REDIRECT_URL`: 微博登录授权回调地址,默认为 `RSSHub 地址/weibo/timeline/0`,自定义回调地址请确保最后可以转跳到 `RSSHub 地址/weibo/timeline/0?code=xxx`
|
||||
|
||||
- 微博 自定义分组
|
||||
|
||||
- `WEIBO_COOKIES`: 用户访问网页微博时所使用的cookie, 获取方式:
|
||||
1. 打开并登录 <https://m.weibo.cn> (确保打开页面为手机版, 如果强制跳转电脑端可尝试使用可更改UserAgent的浏览器插件)
|
||||
2. 按下`F12`打开控制台,切换至`Network(网络)`面板
|
||||
3. 在该网页切换至任意关注分组, 并在面板打开最先捕获到的请求(该情形下捕获到的请求路径应包含`/feed/group`)
|
||||
4. 查看该请求的`Headers(请求头)`, 找到`Cookie`字段并复制内容
|
||||
|
||||
- 小宇宙:需要 App 登陆后抓包获取相应数据。
|
||||
|
||||
- `XIAOYUZHOU_ID`: 即数据包中的 `x-jike-device-id`。
|
||||
|
||||
@@ -1574,6 +1574,22 @@ rule
|
||||
|
||||
</Route>
|
||||
|
||||
### 自定义分组
|
||||
|
||||
<Route author="monologconnor" example="/weibo/group/4541216424989965/微博分组/:routeParams?" path="/weibo/group/:gid/:gname?/:routeParams?" :paramsDesc="['分组id, 在网页版分组地址栏末尾`?gid=`处获取', '分组显示名称; 默认为: `微博分组`', '额外参数;请参阅上面的说明和表格']" anticrawler="1" selfhost="1">
|
||||
|
||||
::: warning 注意
|
||||
|
||||
由于微博官方未提供自定义分组相关api, 此方案必须使用用户`Cookie`进行抓取
|
||||
|
||||
因微博cookies的过期与更新方案未经验证, 部署一次Cookie的有效时长未知
|
||||
|
||||
微博用户Cookie的配置可参照部署文档
|
||||
|
||||
:::
|
||||
|
||||
</Route>
|
||||
|
||||
## 微博绿洲
|
||||
|
||||
### 用户
|
||||
|
||||
@@ -277,6 +277,7 @@ const calculateValue = () => {
|
||||
weibo: {
|
||||
app_key: envs.WEIBO_APP_KEY,
|
||||
app_secret: envs.WEIBO_APP_SECRET,
|
||||
cookies: envs.WEIBO_COOKIES,
|
||||
redirect_url: envs.WEIBO_REDIRECT_URL,
|
||||
},
|
||||
wenku8: {
|
||||
|
||||
99
lib/v2/weibo/group.js
Normal file
99
lib/v2/weibo/group.js
Normal file
@@ -0,0 +1,99 @@
|
||||
const querystring = require('querystring');
|
||||
const got = require('@/utils/got');
|
||||
const config = require('@/config').value;
|
||||
const weiboUtils = require('./utils');
|
||||
const { fallback, queryToBoolean } = require('@/utils/readable-social');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
if (!config.weibo_cookies) {
|
||||
throw 'Weibo Group Timeline is not available due to the absense of [Weibo Cookies]. Check <a href="https://docs.rsshub.app/install/#pei-zhi-bu-fen-rss-mo-kuai-pei-zhi">relevant config tutorial</a>';
|
||||
}
|
||||
|
||||
const gid = ctx.params.gid;
|
||||
const groupName = ctx.params.gname || '微博分组';
|
||||
let displayVideo = '1';
|
||||
let displayArticle = '0';
|
||||
let displayComments = '0';
|
||||
if (ctx.params.routeParams) {
|
||||
if (ctx.params.routeParams === '1' || ctx.params.routeParams === '0') {
|
||||
displayVideo = ctx.params.routeParams;
|
||||
} else {
|
||||
const routeParams = querystring.parse(ctx.params.routeParams);
|
||||
displayVideo = fallback(undefined, queryToBoolean(routeParams.displayVideo), true) ? '1' : '0';
|
||||
displayArticle = fallback(undefined, queryToBoolean(routeParams.displayArticle), false) ? '1' : '0';
|
||||
displayComments = fallback(undefined, queryToBoolean(routeParams.displayComments), false) ? '1' : '0';
|
||||
}
|
||||
}
|
||||
|
||||
const responseData = await ctx.cache.tryGet(
|
||||
`weibo:group:index:${gid}`,
|
||||
async() => {
|
||||
const _r = await got({
|
||||
method: 'get',
|
||||
url: `https://m.weibo.cn/feed/group?gid=${gid}`,
|
||||
headers: {
|
||||
Referer: `https://m.weibo.cn/`,
|
||||
'MWeibo-Pwa': 1,
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'Cookie': config.weibo.cookies,
|
||||
}
|
||||
});
|
||||
return _r.data.data;
|
||||
},
|
||||
config.cache.routeExpire,
|
||||
false
|
||||
);
|
||||
|
||||
const resultItems = await Promise.all(
|
||||
responseData.statuses.map(async (item) => {
|
||||
const retweet = item.retweeted_status;
|
||||
if (retweet && retweet.isLongText) {
|
||||
const retweetData = await ctx.cache.tryGet(`weibo:retweeted:${retweet.user.id}:${retweet.bid}`, () => weiboUtils.getShowData(retweet.user.id, retweet.bid));
|
||||
if (retweetData !== undefined && retweetData.text) {
|
||||
item.retweeted_status.text = retweetData.text;
|
||||
}
|
||||
}
|
||||
|
||||
const link = `https://m.weibo.cn/status/${item.bid}`;
|
||||
const formatExtended = weiboUtils.formatExtended(ctx, item);
|
||||
let description = formatExtended.description;
|
||||
const title = formatExtended.title;
|
||||
const pubDate = item.created_at;
|
||||
|
||||
if (displayVideo === '1') {
|
||||
if (item.retweeted_status) {
|
||||
description = weiboUtils.formatVideo(description, item.retweeted_status);
|
||||
} else {
|
||||
description = weiboUtils.formatVideo(description, item);
|
||||
}
|
||||
}
|
||||
|
||||
if (displayComments === '1') {
|
||||
description = await weiboUtils.formatComments(ctx, description, item);
|
||||
}
|
||||
|
||||
if (displayArticle === '1') {
|
||||
if (item.retweeted_status) {
|
||||
description = await weiboUtils.formatArticle(ctx, description, item.retweeted_status);
|
||||
} else {
|
||||
description = await weiboUtils.formatArticle(ctx, description, item);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
link,
|
||||
pubDate,
|
||||
author: item.user.screen_name
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
ctx.state.data = weiboUtils.sinaimgTvax({
|
||||
title: groupName,
|
||||
link: `https://weibo.com/mygroups?gid=${gid}`,
|
||||
description: '微博自定义分组',
|
||||
item: resultItems,
|
||||
});
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
'/group/:gid/:gname?/:routeParams?': ['monologconnor'],
|
||||
'/keyword/:keyword/:routeParams?': ['DIYgod'],
|
||||
'/oasis/user/:userid': ['kt286'],
|
||||
'/search/hot': ['xyqfer'],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
module.exports = (router) => {
|
||||
router.get('/group/:gid/:gname?/:routeParams?', require('./group'));
|
||||
router.get('/keyword/:keyword/:routeParams?', require('./keyword'));
|
||||
router.get('/oasis/user/:userid', require('./oasis/user'));
|
||||
router.get('/search/hot', require('./search/hot'));
|
||||
|
||||
@@ -94,7 +94,7 @@ module.exports = async (ctx) => {
|
||||
}
|
||||
}
|
||||
|
||||
const link = `https://weibo.com/${uid}/${item.mblog.bid}`;
|
||||
const link = `https://m.weibo.cn/status/${item.mblog.bid}`;
|
||||
const formatExtended = weiboUtils.formatExtended(ctx, item.mblog);
|
||||
let description = formatExtended.description;
|
||||
const title = formatExtended.title;
|
||||
|
||||
Reference in New Issue
Block a user