UNPKG

@hkai-ai/weibo-api

Version:

香港人工智能协会封装的新浪微博API

66 lines (62 loc) 2.67 kB
import { ofetch } from 'ofetch'; import { Effect } from 'effect'; /** * 根据博文 ID 获取 render_data * @param blogId * @returns */ const fetchBlogRenderDataEffect = blogId => Effect.tryPromise({ try: async () => { const url = `https://m.weibo.cn/detail/${blogId}`; const response = await ofetch(url); // 匹配包含 config 和 $render_data 的完整 script 块 const scriptMatch = response.match(/<script>\s*var config = {[\s\S]*?var \$render_data = (\[[\s\S]*?\])\[0\]/); if (scriptMatch?.[1]) { return JSON.parse(scriptMatch[1]); } return null; }, catch: error => new Error(`Failed to fetch render data: ${error.message}`) }); /** * 根据博文 ID 获取 render_data,如果是 null 表示获取失败 * @param blogId * @returns */ export const fetchBlogRenderData = blogId => Effect.runPromise(fetchBlogRenderDataEffect(blogId)); /** * 传入博文详情页内容,返回博文的正文内容,如果博文是转发别人的博文,theRetweetedText 字段会存在值,否则是 undefined * @param renderData * @returns */ const getBlogTrueContent = renderData => { const thePostText = renderData[0].status.text; const thePostId = renderData[0].status.id; const thePostUserInfo = renderData[0].status.user; const thePostMetaData = renderData[0].status; /** * 如果博文是转发别人的博文,那么被转发的博文内容会包含在 retweeted_status 中 */ const theRetweetedText = renderData[0].status?.retweeted_status?.text; const theRetweetedPostId = renderData[0].status?.retweeted_status?.id; const theRetweetedPostUserInfo = renderData[0].status?.retweeted_status?.user; const theRetweetedPostMetaData = renderData[0].status?.retweeted_status; return { thePostText, theRetweetedText, thePostId, theRetweetedPostId, thePostUserInfo, theRetweetedPostUserInfo, thePostMetaData, theRetweetedPostMetaData }; }; export const fetchBlogFullContentEffect = blogId => fetchBlogRenderDataEffect(blogId).pipe(Effect.map(ele => ele === null ? null : getBlogTrueContent(ele)), Effect.tapError(error => Effect.fail(null))); /** * 根据博文 ID 获取博文的全文内容,如果博文存在转发别人的博文,那么被转发的博文内容会存在在 theRetweetedText 字段中,否则该字段的值为 undefined * 如果返回结果是 null,那么表示获取失败 * @param blogId * @returns */ export const fetchBlogFullContent = blogId => Effect.runPromise(fetchBlogRenderDataEffect(blogId).pipe(Effect.map(ele => ele === null ? null : getBlogTrueContent(ele)), Effect.tapError(error => Effect.fail(null))));