Skip to content

Commit

Permalink
feat: retry gamers
Browse files Browse the repository at this point in the history
  • Loading branch information
yjl9903 committed Mar 23, 2024
1 parent 5839cb7 commit b9fd0f6
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 38 deletions.
98 changes: 60 additions & 38 deletions packages/get-bonus/src/gamers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { JSDOM } from 'jsdom';
import { ofetch } from 'ofetch';

import { Provider } from '../scraper';
import { removeExtraSpaces } from '../utils';
import { removeExtraSpaces, retryFn } from '../utils';

export class Gamers extends Provider {
constructor() {
Expand All @@ -17,7 +17,8 @@ export class Gamers extends Provider {
smt: text,
spc: 4,
'nd[]': [5, 6]
}
},
retry: 5
});

const dom = new JSDOM(html);
Expand All @@ -35,46 +36,67 @@ export class Gamers extends Provider {
}

async detail(url: string): Promise<Detail | undefined> {
const html = await ofetch(url);
const dom = new JSDOM(html);
const doc = dom.window.document;
return retryFn(
async () => {
const resp = await ofetch.raw(url, { retry: 5 });

const titleElement = doc.querySelector('.ttl_style01');
const title = titleElement?.textContent?.trim?.() || '';
const html = resp._data! as string;
const dom = new JSDOM(html);
const doc = dom.window.document;

const price = resolvePrice(doc.querySelector('.item_detail_price .price')?.textContent?.trim());
const date = resolveDate(
doc.querySelector('.item_detail_release .release')?.textContent?.trim()
);
const titleElement = doc.querySelector('#item_detail h1');
const title = titleElement?.textContent?.trim?.() || '';

const tokutens = doc.querySelectorAll('#tokuten > div[class]');
const items = [...tokutens].map((item) => {
const img = item.querySelector('img') as HTMLImageElement;
const info = item.querySelector('.tokuten_name');
return <DetailItem>{
image: img.src,
description: removeExtraSpaces(info?.textContent || '')
};
});
/**
* 返回了以下东西, 重试
*
* ただいま、大変サイトが混み合っております。
* 申し訳ありませんが、しばらく時間を置いて
* アクセスしていただけますようお願いいたします。
*/
if (!title) {
throw new Error(doc?.body?.textContent ?? 'Unknown');
}

const isLimited = title.includes("限定版");
if(isLimited == true){
const itemImgMain = doc.querySelector('.item_img_main');
const imgZoom = itemImgMain?.querySelector('.img_zoom') as HTMLImageElement;
items.unshift({
image: imgZoom.src,
description: '此为Gamers限定版。商品信息如图所示。'
});
}

return {
provider: this.id,
title,
date,
price,
url,
items
};
const price = resolvePrice(
doc.querySelector('.item_detail_price .price')?.textContent?.trim()
);
const date = resolveDate(
doc.querySelector('.item_detail_release .release')?.textContent?.trim()
);

const tokutens = doc.querySelectorAll('#tokuten > div[class]');
const items = [...tokutens].map((item) => {
const img = item.querySelector('img') as HTMLImageElement;
const info = item.querySelector('.tokuten_name');
return <DetailItem>{
image: img.src,
description: removeExtraSpaces(info?.textContent || '')
};
});

const isLimited = title.includes('限定版');
if (isLimited == true) {
const itemImgMain = doc.querySelector('.item_img_main');
const imgZoom = itemImgMain?.querySelector('.img_zoom') as HTMLImageElement;
items.unshift({
image: imgZoom.src,
description: '此为Gamers限定版。商品信息如图所示。'
});
}

return {
provider: this.id,
title,
date,
price,
url,
items
};
},
// 重试 5 次, 每次间隔 1 秒
{ retry: 5, delay: 1000 }
);
}
}

Expand Down
23 changes: 23 additions & 0 deletions packages/get-bonus/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
export function removeExtraSpaces(text = '') {
return text.replace(/[ \t]+/g, ' ').trim();
}

export async function retryFn<T>(fn: () => Promise<T>, options: { retry: number; delay?: number }) {
const { retry, delay = 1000 } = options;

let lastError: any;
for (let i = 0; i < retry; i++) {
try {
const result = await fn();
return result;
} catch (error) {
lastError = error;
await sleep(delay);
}
}

throw lastError;
}

export function sleep(timeout: number) {
return new Promise<void>((res) => {
setTimeout(() => res(), timeout);
});
}

0 comments on commit b9fd0f6

Please sign in to comment.