feat(route/zhihu): Replace name fetching logic. (#15733)
* feat(route/zhihu): Replace name fetching logic. * . * Update posts.ts * fix(route): optional `__zse_ck` (#15749) * . * . * Update posts.ts * Update posts.ts * chore: add typing ---------
This commit is contained in:
parent
b393e32906
commit
af0199fbd6
|
|
@ -1,8 +1,9 @@
|
|||
import { Route } from '@/types';
|
||||
import ofetch from '@/utils/ofetch';
|
||||
import cache from '@/utils/cache';
|
||||
import { header, getSignedHeader, processImage } from './utils';
|
||||
import { load } from 'cheerio';
|
||||
import { parseDate } from '@/utils/parse-date';
|
||||
import { Articles, Profile } from './types';
|
||||
|
||||
export const route: Route = {
|
||||
path: '/posts/:usertype/:id',
|
||||
|
|
@ -34,15 +35,19 @@ async function handler(ctx) {
|
|||
const id = ctx.req.param('id');
|
||||
const usertype = ctx.req.param('usertype');
|
||||
|
||||
const data = await ofetch(`https://www.zhihu.com/${usertype}/${id}/posts`, {
|
||||
headers: {
|
||||
...header,
|
||||
Referer: `https://www.zhihu.com/${usertype}/${id}/`,
|
||||
},
|
||||
const userProfile = await cache.tryGet(`zhihu:posts:profile:${id}`, async () => {
|
||||
const userAPIPath = `/api/v4/${usertype === 'people' ? 'members' : 'org'}/${id}?${new URLSearchParams({
|
||||
include: 'allow_message,is_followed,is_following,is_org,is_blocking,employments,answer_count,follower_count,articles_count,gender,badge[?(type=best_answerer)].topics',
|
||||
})}`;
|
||||
|
||||
return await ofetch<Profile>(`https://www.zhihu.com${userAPIPath}`, {
|
||||
headers: {
|
||||
...header,
|
||||
...(await getSignedHeader(`https://www.zhihu.com/${usertype}/${id}/`, userAPIPath)),
|
||||
Referer: `https://www.zhihu.com/${usertype}/${id}/`,
|
||||
},
|
||||
});
|
||||
});
|
||||
const $ = load(data);
|
||||
const initialData = JSON.parse($('#js-initialData').text());
|
||||
const userData = initialData?.initialState?.entities?.users?.[id];
|
||||
|
||||
const apiPath = `/api/v4/${usertype === 'people' ? 'members' : 'org'}/${id}/articles?${new URLSearchParams({
|
||||
include:
|
||||
|
|
@ -54,7 +59,7 @@ async function handler(ctx) {
|
|||
|
||||
const signedHeader = await getSignedHeader(`https://www.zhihu.com/${usertype}/${id}/posts`, apiPath);
|
||||
|
||||
const articleResponse = await ofetch(`https://www.zhihu.com${apiPath}`, {
|
||||
const articleResponse = await ofetch<Articles>(`https://www.zhihu.com${apiPath}`, {
|
||||
headers: {
|
||||
...header,
|
||||
...signedHeader,
|
||||
|
|
@ -72,11 +77,11 @@ async function handler(ctx) {
|
|||
}));
|
||||
|
||||
return {
|
||||
title: `${userData?.name} 的知乎文章`,
|
||||
title: `${userProfile.name} 的知乎文章`,
|
||||
link: `https://www.zhihu.com/${usertype}/${id}/posts`,
|
||||
description: userData?.headline,
|
||||
image: userData?.avatarUrlTemplate?.split('?')[0],
|
||||
banner: userData?.coverUrl?.split('?')[0],
|
||||
description: userProfile.headline,
|
||||
image: userProfile.avatar_url.split('?')[0],
|
||||
// banner: userData?.coverUrl?.split('?')[0],
|
||||
item: items,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
export interface Profile {
|
||||
id: string;
|
||||
url_token: string;
|
||||
name: string;
|
||||
use_default_avatar: boolean;
|
||||
avatar_url: string;
|
||||
avatar_url_template: string;
|
||||
is_org: boolean;
|
||||
type: string;
|
||||
url: string;
|
||||
user_type: string;
|
||||
headline: string;
|
||||
headline_render: string;
|
||||
gender: number;
|
||||
is_advertiser: boolean;
|
||||
ip_info: string;
|
||||
vip_info: {
|
||||
is_vip: boolean;
|
||||
vip_type: number;
|
||||
rename_days: string;
|
||||
entrance_v2: null;
|
||||
rename_frequency: number;
|
||||
rename_await_days: number;
|
||||
};
|
||||
badge: any[];
|
||||
badge_v2: {
|
||||
title: string;
|
||||
merged_badges: any[];
|
||||
detail_badges: any[];
|
||||
icon: string;
|
||||
night_icon: string;
|
||||
};
|
||||
allow_message: boolean;
|
||||
is_following: boolean;
|
||||
is_followed: boolean;
|
||||
is_blocking: boolean;
|
||||
follower_count: number;
|
||||
answer_count: number;
|
||||
articles_count: number;
|
||||
available_medals_count: number;
|
||||
employments: any[];
|
||||
is_realname: boolean;
|
||||
has_applying_column: boolean;
|
||||
}
|
||||
|
||||
interface Article {
|
||||
image_url: string;
|
||||
updated: number;
|
||||
is_jump_native: boolean;
|
||||
is_labeled: boolean;
|
||||
copyright_permission: string;
|
||||
vessay_info: {
|
||||
enable_video_translate: boolean;
|
||||
};
|
||||
excerpt: string;
|
||||
admin_closed_comment: boolean;
|
||||
article_type: string;
|
||||
excerpt_title: string;
|
||||
reaction_instruction: {
|
||||
REACTION_CONTENT_SEGMENT_LIKE: string;
|
||||
};
|
||||
id: number;
|
||||
voteup_count: number;
|
||||
upvoted_followees: [];
|
||||
can_comment: {
|
||||
status: boolean;
|
||||
reason: string;
|
||||
};
|
||||
author: Profile;
|
||||
url: string;
|
||||
comment_permission: string;
|
||||
created: number;
|
||||
image_width: number;
|
||||
content: string;
|
||||
comment_count: number;
|
||||
linkbox: {
|
||||
url: string;
|
||||
category: string;
|
||||
pic: string;
|
||||
title: string;
|
||||
};
|
||||
title: string;
|
||||
voting: number;
|
||||
type: string;
|
||||
suggest_edit: {
|
||||
status: boolean;
|
||||
url: string;
|
||||
reason: string;
|
||||
tip: string;
|
||||
title: string;
|
||||
};
|
||||
is_normal: boolean;
|
||||
}
|
||||
|
||||
export interface Articles {
|
||||
paging: {
|
||||
is_end: boolean;
|
||||
totals: number;
|
||||
previous: string;
|
||||
is_start: boolean;
|
||||
next: string;
|
||||
};
|
||||
data: Article[];
|
||||
}
|
||||
Loading…
Reference in New Issue