Skip to content

Commit

Permalink
fix(route): xiaohongshu user (DIYgod#11949)
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyRL authored Feb 24, 2023
1 parent 09739e3 commit a7cbbf5
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 55 deletions.
4 changes: 2 additions & 2 deletions docs/social-media.md
Original file line number Diff line number Diff line change
Expand Up @@ -1507,9 +1507,9 @@ rule

<Route author="lotosbin" example="/xiaohongshu/user/593032945e87e77791e03696/notes" path="/xiaohongshu/user/:user_id/notes" :paramsDesc="['用户 ID']" puppeteer="1" anticrawler="1" radar="1" rssbud="1"/>

### 用户专辑
### 用户收藏

<Route author="lotosbin" example="/xiaohongshu/user/593032945e87e77791e03696/album" path="/xiaohongshu/user/:user_id/album" :paramsDesc="['用户 ID']" puppeteer="1" anticrawler="1" radar="1" rssbud="1"/>
<Route author="lotosbin" example="/xiaohongshu/user/593032945e87e77791e03696/collect" path="/xiaohongshu/user/:user_id/collect" :paramsDesc="['用户 ID']" puppeteer="1" anticrawler="1" radar="1" rssbud="1"/>

### 专辑

Expand Down
6 changes: 4 additions & 2 deletions lib/v2/xiaohongshu/board.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
const { parseDate } = require('@/utils/parse-date');
const timezone = require('@/utils/timezone');
const { getContent } = require('./util');
const { getBoard } = require('./util');

module.exports = async (ctx) => {
const url = `https://www.xiaohongshu.com/board/${ctx.params.board_id}`;
const main = await getContent(url, ctx.cache);
const main = await getBoard(url, ctx.cache);

const albumInfo = main.albumInfo;
const title = albumInfo.name;
const description = albumInfo.desc;
const image = albumInfo.user.images.split('?imageView2')[0];

const list = main.notesDetail;
const resultItem = list.map((item) => ({
Expand All @@ -22,6 +23,7 @@ module.exports = async (ctx) => {
ctx.state.data = {
title,
link: url,
image,
item: resultItem,
description,
};
Expand Down
3 changes: 2 additions & 1 deletion lib/v2/xiaohongshu/maintainer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
'/board/:board_id': ['lotosbin'],
'/user/:user_id/:category': ['lotosbin'],
'/user/:user_id/collect': ['lotosbin'],
'/user/:user_id/notes': ['lotosbin'],
};
4 changes: 2 additions & 2 deletions lib/v2/xiaohongshu/radar.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ module.exports = {
target: '/xiaohongshu/user/:user_id/notes',
},
{
title: '用户专辑',
title: '用户收藏',
docs: 'https://docs.rsshub.app/social-media.html#xiao-hong-shu',
source: '/user/profile/:user_id',
target: '/xiaohongshu/user/:user_id/album',
target: '/xiaohongshu/user/:user_id/collect',
},
{
title: '专辑',
Expand Down
61 changes: 20 additions & 41 deletions lib/v2/xiaohongshu/user.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,30 @@
const { parseDate } = require('@/utils/parse-date');
const timezone = require('@/utils/timezone');
const { getContent } = require('./util');
const { getUser } = require('./util');

module.exports = async (ctx) => {
const userId = ctx.params.user_id;
const category = ctx.params.category;
const url = `https://www.xiaohongshu.com/user/profile/${userId}`;

let main;
try {
main = await getContent(url, ctx.cache);
} catch (e) {
throw Error('滑块验证');
}
const userDetail = main.userDetail;
const description = `${userDetail.nickname} • 小红书 / RED`;
if (category === 'notes') {
const list = main.notesDetail;
const resultItem = list.map((item) => ({
title: item.title,
link: `https://www.xiaohongshu.com/discovery/item/${item.id}`,
description: `<img src ="${item.cover.url.split('?imageView2')[0]}"><br>${item.title}`,
author: item.user.nickname,
pubDate: timezone(parseDate(item.time), 8),
}));
const content = await getUser(url, ctx.cache);

const title = `小红书-${userDetail.nickname}-笔记`;
ctx.state.data = {
title,
link: url,
item: resultItem,
description,
};
} else if (category === 'album') {
const list = main.albumDetail;
const resultItem = list.map((item) => ({
title: item.title,
link: `https://www.xiaohongshu.com/board/${item.id}`,
description: item.images.map((it) => `<img src ="${it.split('?imageView2')[0]}">`).join(`<br>`),
const { otherInfo, user_posted, collect } = content;
const title = `${otherInfo.data.basic_info.nickname} - ${category === 'notes' ? '笔记' : '收藏'} • 小红书 / RED`;
const description = otherInfo.data.basic_info.desc;
const image = otherInfo.data.basic_info.imageb || otherInfo.data.basic_info.images;

const items = (category, user_posted, collect) =>
(category === 'notes' ? user_posted : collect).data.notes.map((item) => ({
title: item.display_title,
link: `${url}/${item.note_id}`,
description: `<img src ="${item.cover.url}"><br>${item.display_title}`,
author: item.user.nickname,
}));

const title = `小红书-${userDetail.nickname}-专辑`;
ctx.state.data = {
title,
link: url,
item: resultItem,
description,
};
}
ctx.state.data = {
title,
description,
image,
link: url,
item: items(category, user_posted, collect),
};
};
51 changes: 44 additions & 7 deletions lib/v2/xiaohongshu/util.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,58 @@
const config = require('@/config').value;
const logger = require('@/utils/logger');

const getContent = (url, cache) =>
const getUser = (url, cache) =>
cache.tryGet(
url,
async () => {
const browser = await require('@/utils/puppeteer')();
try {
const page = await browser.newPage();
await page.setRequestInterception(true);
let otherInfo = '';
let user_posted = '';
let collect = '';
page.on('request', (request) => {
request.resourceType() === 'document' || request.resourceType() === 'script' || request.resourceType() === 'xhr' ? request.continue() : request.abort();
request.resourceType() === 'document' || request.resourceType() === 'script' || request.resourceType() === 'xhr' || request.resourceType() === 'other' ? request.continue() : request.abort();
});
page.on('response', (response) => {
if (response.url().includes('captcha.fengkongcloud.cn')) {
page.close();
throw Error('滑块验证');
page.on('response', async (response) => {
const request = response.request();
if (request.url().includes('/api/sns/web/v1/user/otherinfo')) {
otherInfo = await response.json();
}
if (request.url().includes('/api/sns/web/v1/user_posted')) {
user_posted = await response.json();
}
if (request.url().includes('/api/sns/web/v2/note/collect/page')) {
collect = await response.json();
}
});
logger.debug(`Requesting ${url}`);
await page.goto(url);
await page.waitForSelector('.feeds-container:nth-child(1) .note-item');
await page.click('div.reds-tab-item:nth-child(2)');
await page.waitForSelector('.feeds-container:nth-child(2) .note-item');
return { otherInfo, user_posted, collect };
} finally {
browser.close();
}
},
config.cache.routeExpire,
false
);

const getBoard = (url, cache) =>
cache.tryGet(
url,
async () => {
const browser = await require('@/utils/puppeteer')();
try {
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', (request) => {
request.resourceType() === 'document' || request.resourceType() === 'script' || request.resourceType() === 'xhr' ? request.continue() : request.abort();
});
logger.debug(`Requesting ${url}`);
await page.goto(url);
await page.waitForSelector('.pc-container');
const initialSsrState = await page.evaluate(() => window.__INITIAL_SSR_STATE__);
Expand All @@ -30,5 +66,6 @@ const getContent = (url, cache) =>
);

module.exports = {
getContent,
getUser,
getBoard,
};

0 comments on commit a7cbbf5

Please sign in to comment.