rsshub
Version:
Make RSS Great Again!
93 lines (89 loc) • 3.13 kB
text/typescript
import { Route, Data } from '@/types';
import puppeteer from '@/utils/puppeteer';
import { config } from '@/config';
export const route: Route = {
name: 'Profile',
path: '/profile/:principalId',
radar: [
{
source: ['kuaishou.com/profile/:principalId'],
target: '/profile/:principalId',
},
],
parameters: {
principalId: '用户 id, 可在主页中找到',
},
example: '/kuaishou/profile/3xk46q9cdnvgife',
maintainers: ['GuoChen-thlg'],
url: 'kuaishou.com/profile/:principalId',
description: `::: tip
The profile page of the user, which contains the user's information, videos, and other information.
:::`,
handler,
};
async function handler(ctx) {
const { principalId } = ctx.req.param();
const browser = await puppeteer();
const page = await browser.newPage();
let retryCount = 0;
let resolve;
let userInfo;
const promise = new Promise((res) => {
resolve = res;
});
await page.setRequestInterception(true);
page.on('request', (req) => {
const resourceType = req.resourceType();
if (resourceType === 'image' || resourceType === 'media' || resourceType === 'font' || resourceType === 'stylesheet' || resourceType === 'ping') {
req.abort();
} else {
req.continue();
}
});
page.on('response', async (res) => {
if (res.ok() && res.url().includes('/live_api/profile/public')) {
const resData = await res.json();
if (resData.data.list.length > 0) {
resolve(resData.data);
} else {
if (retryCount > config.requestRetry) {
resolve({});
}
setTimeout(() => {
page.reload().then();
retryCount++;
}, 3000);
}
} else if (res.ok() && res.url().includes('/live_api/baseuser/userinfo/byid')) {
// principalId
const resData = await res.json();
userInfo = resData.data.userInfo;
}
});
await page.goto('https://www.kuaishou.com', {
waitUntil: 'domcontentloaded',
});
await page.goto(`https://live.kuaishou.com/profile/${principalId}`);
const resData = (await promise.catch((error) => error)) as Array<any>;
await browser.close();
const data: Data = {
title: userInfo?.name ?? `${principalId}的作品 - 快手`,
// description: JSON.stringify(resData),
item:
resData?.list?.map((item) => ({
// title: '',
author: item.author.name,
description: `<video controls preload="metadata" poster="${item.poster}">
<source src="${item.playUrl}" type="video/mp4">
</video>`,
// link: '',
id: item.id,
guid: item.id,
banner: item.poster,
media: {
content: { url: item.playUrl },
},
})) || [],
};
return data;
}