mirror of
https://github.com/DIYgod/RSSHub.git
synced 2026-10-24 12:15:32 +08:00
fix(route/weibo/utils): tryWithCookies: Cookies expiration not detected (#20583)
* feat(route/weibo/utils): getCookies: Add cooldown time Signed-off-by: Rongrong <i@rong.moe> * fix(route/weibo/utils): tryWithCookies: Cookies expiration not detected Signed-off-by: Rongrong <i@rong.moe> --------- Signed-off-by: Rongrong <i@rong.moe>
This commit is contained in:
@@ -38,7 +38,7 @@ export const route: Route = {
|
||||
async function handler(ctx) {
|
||||
const keyword = ctx.req.param('keyword');
|
||||
|
||||
const data = await weiboUtils.tryWithCookies((cookies) =>
|
||||
const data = await weiboUtils.tryWithCookies((cookies, verifier) =>
|
||||
cache.tryGet(
|
||||
`weibo:keyword:${keyword}`,
|
||||
async () => {
|
||||
@@ -51,6 +51,7 @@ async function handler(ctx) {
|
||||
...weiboUtils.apiHeaders,
|
||||
},
|
||||
});
|
||||
verifier(_r);
|
||||
return _r.data.data.cards;
|
||||
},
|
||||
config.cache.routeExpire,
|
||||
|
||||
@@ -59,8 +59,8 @@ async function handler(ctx) {
|
||||
fullpic = ctx.req.query('fullpic') ?? 'false';
|
||||
const {
|
||||
data: { data },
|
||||
} = await weiboUtils.tryWithCookies((cookies) =>
|
||||
got({
|
||||
} = await weiboUtils.tryWithCookies(async (cookies, verifier) => {
|
||||
const _r = await got({
|
||||
method: 'get',
|
||||
url: 'https://m.weibo.cn/api/container/getIndex?containerid=106003type%3D25%26t%3D3%26disable_hot%3D1%26filter_type%3Drealtimehot&title=%E5%BE%AE%E5%8D%9A%E7%83%AD%E6%90%9C&extparam=filter_type%3Drealtimehot%26mi_cid%3D100103%26pos%3D0_0%26c_type%3D30%26display_time%3D1540538388&luicode=10000011&lfid=231583',
|
||||
headers: {
|
||||
@@ -68,8 +68,10 @@ async function handler(ctx) {
|
||||
Cookie: cookies,
|
||||
...weiboUtils.apiHeaders,
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
verifier(_r);
|
||||
return _r;
|
||||
});
|
||||
|
||||
let resultItems = null;
|
||||
if (ctx.req.param('fulltext') === 'fulltext') {
|
||||
|
||||
@@ -53,7 +53,7 @@ async function handler(ctx) {
|
||||
const id = ctx.req.param('id');
|
||||
const type = ctx.req.param('type') ?? 'feed';
|
||||
|
||||
const containerData = (await weiboUtils.tryWithCookies((cookies) =>
|
||||
const containerData = (await weiboUtils.tryWithCookies((cookies, verifier) =>
|
||||
cache.tryGet(
|
||||
`weibo:super_index:container:${id}:${type}`,
|
||||
async () => {
|
||||
@@ -69,6 +69,7 @@ async function handler(ctx) {
|
||||
...weiboUtils.apiHeaders,
|
||||
},
|
||||
});
|
||||
verifier(_r);
|
||||
return _r.data.data;
|
||||
},
|
||||
config.cache.routeExpire,
|
||||
|
||||
@@ -73,7 +73,7 @@ async function handler(ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
const containerData = await weiboUtils.tryWithCookies((cookies) =>
|
||||
const containerData = await weiboUtils.tryWithCookies((cookies, verifier) =>
|
||||
cache.tryGet(
|
||||
`weibo:user:index:${uid}`,
|
||||
async () => {
|
||||
@@ -86,6 +86,7 @@ async function handler(ctx) {
|
||||
...weiboUtils.apiHeaders,
|
||||
},
|
||||
});
|
||||
verifier(_r);
|
||||
return _r.data;
|
||||
},
|
||||
config.cache.routeExpire,
|
||||
@@ -98,7 +99,7 @@ async function handler(ctx) {
|
||||
const profileImageUrl = containerData.data.userInfo.profile_image_url;
|
||||
const containerId = containerData.data.tabsInfo.tabs.find((item) => item.tab_type === 'weibo').containerid;
|
||||
|
||||
const cards = await weiboUtils.tryWithCookies((cookies) =>
|
||||
const cards = await weiboUtils.tryWithCookies((cookies, verifier) =>
|
||||
cache.tryGet(
|
||||
`weibo:user:cards:${uid}:${containerId}`,
|
||||
async () => {
|
||||
@@ -111,6 +112,7 @@ async function handler(ctx) {
|
||||
...weiboUtils.apiHeaders,
|
||||
},
|
||||
});
|
||||
verifier(_r);
|
||||
return _r.data.data.cards;
|
||||
},
|
||||
config.cache.routeExpire,
|
||||
|
||||
+70
-50
@@ -24,62 +24,82 @@ const weiboUtils = {
|
||||
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
|
||||
},
|
||||
RenewWeiboCookiesError,
|
||||
getCookies: async (renew = false) => {
|
||||
if (config.weibo.cookies) {
|
||||
if (renew) {
|
||||
throw new Error('Cookies expired. Please update WEIBO_COOKIES');
|
||||
}
|
||||
return config.weibo.cookies;
|
||||
}
|
||||
getCookies: (() => {
|
||||
const url = 'https://m.weibo.cn/';
|
||||
const coolingDownMessage = `Cooling down before new visitor Cookies from ${url} may be fetched`;
|
||||
let coolingDown: boolean = false;
|
||||
|
||||
const cacheKey = 'weibo:guest-cookies';
|
||||
if (renew) {
|
||||
cache.set(cacheKey, '', 1);
|
||||
}
|
||||
return await cache.tryGet(cacheKey, async () => {
|
||||
const url = 'https://m.weibo.cn/';
|
||||
return async (renew: any = false) => {
|
||||
if (config.weibo.cookies) {
|
||||
if (renew) {
|
||||
throw new Error('Cookies expired. Please update WEIBO_COOKIES');
|
||||
}
|
||||
return config.weibo.cookies;
|
||||
}
|
||||
|
||||
const cacheKey = 'weibo:visitor-cookies';
|
||||
if (renew) {
|
||||
logger.warn(`Renewing visitor Cookies from ${url}`);
|
||||
} else {
|
||||
logger.info(`Fetching visitor Cookies from ${url}`);
|
||||
cache.set(cacheKey, '', 1);
|
||||
}
|
||||
let times = 0;
|
||||
const { page, destory } = await getPuppeteerPage(url, {
|
||||
onBeforeLoad: async (page) => {
|
||||
const expectResourceTypes = new Set(['document', 'script', 'xhr', 'fetch']);
|
||||
await page.setUserAgent(weiboUtils.apiHeaders['User-Agent']);
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', (request) => {
|
||||
// 1st: initial request, 302 to visitor.passport.weibo.cn; 2nd: auth ok
|
||||
if (!expectResourceTypes.has(request.resourceType()) || times >= 2) {
|
||||
request.abort();
|
||||
return;
|
||||
}
|
||||
if (request.url().startsWith(url)) {
|
||||
times++;
|
||||
}
|
||||
request.continue();
|
||||
});
|
||||
},
|
||||
// networkidle2 returns too early if the connection is slow
|
||||
gotoConfig: { waitUntil: 'networkidle0' },
|
||||
return await cache.tryGet(cacheKey, async () => {
|
||||
if (coolingDown) {
|
||||
if (renew?.message) {
|
||||
logger.warn(coolingDownMessage);
|
||||
throw renew;
|
||||
} else {
|
||||
throw new Error(coolingDownMessage);
|
||||
}
|
||||
}
|
||||
coolingDown = true;
|
||||
setTimeout(() => {
|
||||
coolingDown = false;
|
||||
}, config.cache.routeExpire * 1000);
|
||||
|
||||
if (renew) {
|
||||
logger.warn(`Renewing visitor Cookies from ${url}`);
|
||||
} else {
|
||||
logger.info(`Fetching visitor Cookies from ${url}`);
|
||||
}
|
||||
let times = 0;
|
||||
const { page, destory } = await getPuppeteerPage(url, {
|
||||
onBeforeLoad: async (page) => {
|
||||
const expectResourceTypes = new Set(['document', 'script', 'xhr', 'fetch']);
|
||||
await page.setUserAgent(weiboUtils.apiHeaders['User-Agent']);
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', (request) => {
|
||||
// 1st: initial request, 302 to visitor.passport.weibo.cn; 2nd: auth ok
|
||||
if (!expectResourceTypes.has(request.resourceType()) || times >= 2) {
|
||||
request.abort();
|
||||
return;
|
||||
}
|
||||
if (request.url().startsWith(url)) {
|
||||
times++;
|
||||
}
|
||||
request.continue();
|
||||
});
|
||||
},
|
||||
// networkidle2 returns too early if the connection is slow
|
||||
gotoConfig: { waitUntil: 'networkidle0' },
|
||||
});
|
||||
const cookies: string = await getCookies(page, 'weibo.cn');
|
||||
await destory();
|
||||
if (times < 2 || !cookies) {
|
||||
throw new Error(`Unable to fetch visitor cookies. Please set WEIBO_COOKIES. Redirection: ${times}, last URL: ${page.url()}`);
|
||||
}
|
||||
return cookies;
|
||||
});
|
||||
const cookies: string = await getCookies(page, 'weibo.cn');
|
||||
await destory();
|
||||
if (times < 2) {
|
||||
throw new Error(`Unexpected redirection. Last URL: ${page.url()}`);
|
||||
}
|
||||
if (!cookies) {
|
||||
throw new Error(`Unable to fetch visitor cookies. Please set WEIBO_COOKIES. Last URL: ${page.url()}`);
|
||||
}
|
||||
return cookies;
|
||||
});
|
||||
},
|
||||
};
|
||||
})(),
|
||||
tryWithCookies: (() => {
|
||||
let errors: number = 0;
|
||||
return async (callback: (cookies: string) => Promise<any>) => {
|
||||
const verifier = (resp: any): void => {
|
||||
if (resp?.data?.ok === -100) {
|
||||
throw new RenewWeiboCookiesError(`Cookies expired. Msg: ${resp?.data?.msg || ''} ${resp?.data?.url || ''}`);
|
||||
}
|
||||
};
|
||||
return async <T>(callback: (cookies: string, verifier: (resp: any) => void) => Promise<T>): Promise<T> => {
|
||||
try {
|
||||
return await callback(await weiboUtils.getCookies(false));
|
||||
return await callback(await weiboUtils.getCookies(false), verifier);
|
||||
} catch (error: any) {
|
||||
if (error.message?.includes('WEIBO_COOKIES')) {
|
||||
throw error;
|
||||
@@ -96,7 +116,7 @@ const weiboUtils = {
|
||||
throw error;
|
||||
}
|
||||
errors = 0;
|
||||
return await callback(await weiboUtils.getCookies(true));
|
||||
return await callback(await weiboUtils.getCookies(error), verifier);
|
||||
}
|
||||
};
|
||||
})(),
|
||||
|
||||
Reference in New Issue
Block a user