-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add an router for getting all collections of a user in zhihu.co…
…m. (#18028) * 添加知乎路由,用于获取指定用户所有公开的收藏内容 * 修改example地址 * 修改代码以符合路由规范 * Update lib/routes/zhihu/all-collections.ts Co-authored-by: Tony <TonyRL@users.noreply.github.com> * 修改代码以符合路由规范和代码审阅者要求的got请求代码格式统一和re-cast的问题 --------- Co-authored-by: yuerongkang <yuerongkang@drivedream.com>
- Loading branch information
1 parent
1e246f2
commit c405ee8
Showing
2 changed files
with
135 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { Route, ViewType, Collection, CollectionItem } from '@/types'; | ||
import got from '@/utils/got'; | ||
import { header } from './utils'; | ||
import { parseDate } from '@/utils/parse-date'; | ||
import cache from '@/utils/cache'; | ||
|
||
export const route: Route = { | ||
path: '/people/allCollections/:id', | ||
categories: ['social-media'], | ||
view: ViewType.Articles, | ||
example: '/zhihu/people/allCollections/87-44-49-67', | ||
parameters: { id: '作者 id,可在用户主页 URL 中找到' }, | ||
features: { | ||
requireConfig: false, | ||
requirePuppeteer: false, | ||
antiCrawler: true, | ||
supportBT: false, | ||
supportPodcast: false, | ||
supportScihub: false, | ||
}, | ||
radar: [ | ||
{ | ||
source: ['www.zhihu.com/people/:id'], | ||
// target: 'people/allCollections/:id', | ||
}, | ||
], | ||
name: '用户全部收藏内容', | ||
maintainers: ['Healthyyue'], | ||
handler, | ||
}; | ||
|
||
async function handler(ctx) { | ||
const id = ctx.req.param('id'); | ||
const apiPath = `https://api.zhihu.com/people/${id}/collections`; | ||
|
||
const response = await got(apiPath, { | ||
headers: { | ||
Referer: `https://www.zhihu.com/people/${id}/collections`, | ||
}, | ||
}); | ||
|
||
const collections = response.data.data as Collection[]; | ||
|
||
const allCollectionItems = await Promise.all( | ||
collections.map(async (collection) => { | ||
const firstPageResponse = await got(`https://www.zhihu.com/api/v4/collections/${collection.id}/items?offset=0&limit=20`, { | ||
headers: { | ||
...header, | ||
Referer: `https://www.zhihu.com/collection/${collection.id}`, | ||
}, | ||
}); | ||
|
||
const { | ||
data: items, | ||
paging: { totals }, | ||
} = firstPageResponse.data; | ||
|
||
if (totals > 20) { | ||
const offsetList = Array.from({ length: Math.ceil(totals / 20) - 1 }, (_, index) => (index + 1) * 20); | ||
|
||
const otherPages = await Promise.all( | ||
offsetList.map((offset) => | ||
cache.tryGet(`https://www.zhihu.com/api/v4/collections/${collection.id}/items?offset=${offset}&limit=20`, async () => { | ||
const response = await got(`https://www.zhihu.com/api/v4/collections/${collection.id}/items?offset=${offset}&limit=20`, { | ||
headers: { | ||
...header, | ||
Referer: `https://www.zhihu.com/collection/${collection.id}`, | ||
}, | ||
}); | ||
return response.data.data; | ||
}) | ||
) | ||
); | ||
|
||
items.push(...otherPages.flat()); | ||
} | ||
|
||
return { | ||
collectionId: collection.id, | ||
collectionTitle: collection.title, | ||
items, | ||
}; | ||
}) | ||
); | ||
|
||
const items = allCollectionItems.flatMap( | ||
(collection) => | ||
collection.items.map((item) => ({ | ||
...item, | ||
collectionTitle: collection.collectionTitle, | ||
})) as CollectionItem[] | ||
); | ||
|
||
return { | ||
title: `${collections[0].creator.name}的知乎收藏`, | ||
link: `https://www.zhihu.com/people/${id}/collections`, | ||
item: items.map((item) => { | ||
const content = item.content; | ||
|
||
return { | ||
title: content.type === 'article' || content.type === 'zvideo' ? content.title : content.question.title, | ||
link: content.url, | ||
description: content.type === 'zvideo' ? `<img src=${content.video.url}/>` : content.content, | ||
pubDate: parseDate((content.type === 'article' ? content.updated : content.updated_time) * 1000), | ||
category: [item.collectionTitle], | ||
}; | ||
}), | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters