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:
Andvari 2024-05-29 22:58:57 +08:00 committed by GitHub
parent b393e32906
commit af0199fbd6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 123 additions and 14 deletions

View File

@ -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,
};
}

104
lib/routes/zhihu/types.ts Normal file
View File

@ -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[];
}