mirror of
https://github.com/DIYgod/RSSHub.git
synced 2025-12-10 07:12:51 +08:00
feat: 品玩 (#2764)
* fix docs * feat: 字幕库 * feat: hpoi info * fix hpoi 情报 文案 * feat: 品玩 * fix: hpoi info category * fix: add referer * fix format Co-authored-by: DIYgod <diy.d.god@gmail.com>
This commit is contained in:
@@ -729,6 +729,36 @@ type 为 all 时,category 参数不支持 cost 和 free
|
||||
|
||||
<Route author="qiwihui" example="/paidai/news" path="/paidao/news" />
|
||||
|
||||
## 品玩
|
||||
|
||||
### 实时要闻
|
||||
|
||||
<Route author="sanmmm" example="/pingwest/status" path="/pingwest/status"/>
|
||||
|
||||
### 话题动态
|
||||
|
||||
<Route author="sanmmm" path="/pingwest/tag/:tag/:type" example="/pingwest/tag/ChinaJoy/1" :paramsDesc="['话题名或话题id, 可从话题页url中得到', '内容类型']">
|
||||
|
||||
内容类型
|
||||
|
||||
| 最新 | 最热 |
|
||||
| ---- | ---- |
|
||||
| 1 | 2 |
|
||||
|
||||
</Route>
|
||||
|
||||
### 用户
|
||||
|
||||
<Route author="sanmmm" path="/pingwest/user/:uid/:type?" example="/pingwest/user/7781550877/article" :paramsDesc="['用户id, 可从用户主页中得到', '内容类型, 默认为`article`']">
|
||||
|
||||
内容类型
|
||||
|
||||
| 文章 | 动态 |
|
||||
| ------- | ----- |
|
||||
| article | state |
|
||||
|
||||
</Route>
|
||||
|
||||
## 且听风吟福利
|
||||
|
||||
### 分类
|
||||
|
||||
@@ -1618,6 +1618,11 @@ router.get('/mofcom/article/:suffix', require('./routes/mofcom/article'));
|
||||
// 字幕库
|
||||
router.get('/zimuku/:type?', require('./routes/zimuku/index'));
|
||||
|
||||
// 品玩
|
||||
router.get('/pingwest/status', require('./routes/pingwest/status'));
|
||||
router.get('/pingwest/tag/:tag/:type', require('./routes/pingwest/tag'));
|
||||
router.get('/pingwest/user/:uid/:type?', require('./routes/pingwest/user'));
|
||||
|
||||
// Hanime
|
||||
router.get('/hanime/video', require('./routes/hanime/video'));
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ module.exports = async (ctx) => {
|
||||
return {
|
||||
title: infoTitle,
|
||||
link,
|
||||
category: infoType,
|
||||
description: [`类型:${typeName}`, infoTitle, `更新内容: ${infoType}`, `<img src=""${imgUrl}/>`].join('<br/>'),
|
||||
};
|
||||
})
|
||||
|
||||
43
lib/routes/pingwest/status.js
Normal file
43
lib/routes/pingwest/status.js
Normal file
@@ -0,0 +1,43 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const baseUrl = 'https://www.pingwest.com';
|
||||
const url = `${baseUrl}/api/state/list`;
|
||||
const response = await got(url, {
|
||||
query: {
|
||||
page: 1,
|
||||
},
|
||||
headers: {
|
||||
Referer: baseUrl,
|
||||
},
|
||||
});
|
||||
const $ = cheerio.load(response.data.data.list);
|
||||
const items = $('section.item')
|
||||
.map((_, ele) => {
|
||||
const timestamp = ele.attribs['data-t'];
|
||||
const $item = cheerio.load(ele);
|
||||
const rightNode = $item('.news-info');
|
||||
const tag = rightNode.find('.item-tag-list').text();
|
||||
const title = rightNode.find('.title').text();
|
||||
const link = rightNode
|
||||
.find('a')
|
||||
.last()
|
||||
.attr('href');
|
||||
const description = rightNode.text();
|
||||
return {
|
||||
title: title || tag,
|
||||
link: link.startsWith('http') ? link : `https:${link}`,
|
||||
description,
|
||||
pubDate: new Date(timestamp * 1000).toUTCString(),
|
||||
};
|
||||
})
|
||||
.get();
|
||||
|
||||
ctx.state.data = {
|
||||
title: '品玩 - 实时要闻',
|
||||
description: '品玩 - 实时要闻',
|
||||
link: `${baseUrl}/status`,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
50
lib/routes/pingwest/tag.js
Normal file
50
lib/routes/pingwest/tag.js
Normal file
@@ -0,0 +1,50 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const utils = require('./utils');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { tag, type } = ctx.params;
|
||||
const baseUrl = 'https://www.pingwest.com';
|
||||
const tagUrl = `${baseUrl}/tag/${tag}`;
|
||||
const tagId = await ctx.cache.tryGet(`pingwest-tag-${tag}`, async () => {
|
||||
const res = await got(encodeURI(tagUrl), {
|
||||
headers: {
|
||||
Referer: baseUrl,
|
||||
},
|
||||
});
|
||||
const $ = cheerio.load(res.data);
|
||||
const tagId = $('.tag-detail').attr('data-id');
|
||||
return tagId;
|
||||
});
|
||||
const url = `${baseUrl}/api/tag_article_list`;
|
||||
const response = await got(url, {
|
||||
query: {
|
||||
page: 1,
|
||||
id: tagId,
|
||||
type,
|
||||
},
|
||||
headers: {
|
||||
Referer: baseUrl,
|
||||
},
|
||||
});
|
||||
const $ = cheerio.load(response.data.data.list);
|
||||
const items = $('.item')
|
||||
.map((_, ele) => {
|
||||
const className = ele.attribs.class;
|
||||
if (className.includes('state')) {
|
||||
return utils.statusListParser(cheerio.load(ele))[0];
|
||||
}
|
||||
if (className.includes('wire')) {
|
||||
return utils.wireListParser(cheerio.load(ele))[0];
|
||||
}
|
||||
return utils.articleListParser(cheerio.load(ele))[0];
|
||||
})
|
||||
.get();
|
||||
|
||||
ctx.state.data = {
|
||||
title: `品玩 - ${tag}`,
|
||||
description: `品玩 - ${tag}`,
|
||||
link: tagUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
55
lib/routes/pingwest/user.js
Normal file
55
lib/routes/pingwest/user.js
Normal file
@@ -0,0 +1,55 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const utils = require('./utils');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { uid, type = 'article' } = ctx.params;
|
||||
const baseUrl = 'https://www.pingwest.com';
|
||||
const aimUrl = `${baseUrl}/user/${uid}/${type}`;
|
||||
const { userName, realUid } = await ctx.cache.tryGet(`pingwest-user-info-${uid}`, async () => {
|
||||
const res = await got(aimUrl, {
|
||||
headers: {
|
||||
Referer: baseUrl,
|
||||
},
|
||||
});
|
||||
const $ = cheerio.load(res.data);
|
||||
const userInfoNode = $('#J_userId');
|
||||
return {
|
||||
userName: userInfoNode.text(),
|
||||
realUid: userInfoNode.attr('data-user-id'),
|
||||
};
|
||||
});
|
||||
const url = `${baseUrl}/api/user_data`;
|
||||
const response = await got(url, {
|
||||
query: {
|
||||
page: 1,
|
||||
user_id: realUid,
|
||||
tab: type,
|
||||
},
|
||||
headers: {
|
||||
Referer: baseUrl,
|
||||
},
|
||||
});
|
||||
const $ = cheerio.load(response.data.data.list);
|
||||
|
||||
let item = [];
|
||||
switch (type) {
|
||||
case 'article':
|
||||
item = utils.articleListParser($);
|
||||
break;
|
||||
case 'state':
|
||||
item = utils.statusListParser($);
|
||||
break;
|
||||
}
|
||||
|
||||
const typeToLabel = {
|
||||
article: '文章',
|
||||
state: '动态',
|
||||
};
|
||||
ctx.state.data = {
|
||||
title: `品玩 - ${userName} - ${typeToLabel[type]}`,
|
||||
description: `品玩 - ${userName} - ${typeToLabel[type]}`,
|
||||
link: aimUrl,
|
||||
item,
|
||||
};
|
||||
};
|
||||
79
lib/routes/pingwest/utils.js
Normal file
79
lib/routes/pingwest/utils.js
Normal file
@@ -0,0 +1,79 @@
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
const statusListParser = ($) => {
|
||||
const items = $('.item')
|
||||
.map((_, ele) => {
|
||||
const timestamp = ele.attribs.pt;
|
||||
const $item = cheerio.load(ele);
|
||||
const mainNode = $item('.news-detail');
|
||||
const imgsStr = mainNode
|
||||
.find('img')
|
||||
.map((_, ele) => `<img src="${ele.attribs.src}"/>`)
|
||||
.get()
|
||||
.join('<br/>');
|
||||
const link = mainNode
|
||||
.find('.content a')
|
||||
.first()
|
||||
.attr('href');
|
||||
const content = mainNode
|
||||
.text()
|
||||
.trim()
|
||||
.replace(/展开全文$/, '');
|
||||
return {
|
||||
title: content,
|
||||
link: link.startsWith('http') ? link : `https:${link}`,
|
||||
description: [content, imgsStr].filter((s) => !!s).join('<br/>'),
|
||||
pubDate: new Date(timestamp * 1000).toUTCString(),
|
||||
};
|
||||
})
|
||||
.get();
|
||||
return items;
|
||||
};
|
||||
|
||||
const articleListParser = ($) => {
|
||||
const items = $('.item')
|
||||
.map((_, ele) => {
|
||||
const $item = cheerio.load(ele);
|
||||
const timestamp = ele.attribs.pt;
|
||||
const imgUrl = $item('.news-img img').attr('src');
|
||||
const titleNode = $item('.title').first();
|
||||
const title = titleNode.text();
|
||||
const link = titleNode.find('a').attr('href');
|
||||
const description = $item('.desc').text();
|
||||
const author = $item('.author a').text();
|
||||
return {
|
||||
title,
|
||||
link: link.startsWith('http') ? link : `https:${link}`,
|
||||
description: [description, `<img src="${imgUrl}"/>`].join('<br/>'),
|
||||
author,
|
||||
pubDate: new Date(timestamp * 1000).toUTCString(),
|
||||
};
|
||||
})
|
||||
.get();
|
||||
return items;
|
||||
};
|
||||
|
||||
const wireListParser = ($) => {
|
||||
const items = $('.item')
|
||||
.map((_, ele) => {
|
||||
const $item = cheerio.load(ele);
|
||||
const timestamp = ele.attribs.pt;
|
||||
const titleNode = $item('.text').first();
|
||||
const title = titleNode.text();
|
||||
const link = titleNode.find('a').attr('href');
|
||||
return {
|
||||
title,
|
||||
link: link.startsWith('http') ? link : `https:${link}`,
|
||||
description: title,
|
||||
pubDate: new Date(timestamp * 1000).toUTCString(),
|
||||
};
|
||||
})
|
||||
.get();
|
||||
return items;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
articleListParser,
|
||||
statusListParser,
|
||||
wireListParser,
|
||||
};
|
||||
Reference in New Issue
Block a user