gpt4free-ts/pool/puppeteer.ts

104 行
2.7 KiB
TypeScript
Raw 通常表示 履歴

2023-05-12 18:16:25 +09:00
import puppeteer, {Browser, Page, PuppeteerLaunchOptions} from "puppeteer";
import fs from 'fs';
import path from "path";
import run from "node:test";
2023-06-04 14:14:28 +09:00
import {v4} from "uuid";
2023-05-12 18:16:25 +09:00
const runPath = path.join(__dirname, 'run');
export class FreeBrowser {
private browser: Browser | undefined = undefined;
private readonly options: PuppeteerLaunchOptions | undefined;
private urls: Set<string> = new Set<string>();
private pages: Record<string, Page> = {};
2023-06-04 14:14:28 +09:00
public readonly id: string;
2023-05-12 18:16:25 +09:00
constructor(id: string, options?: PuppeteerLaunchOptions) {
this.options = {
2023-06-04 13:43:13 +09:00
// userDataDir: path.join(runPath, id),
2023-05-12 18:16:25 +09:00
...options
};
this.id = id;
}
public async init() {
this.browser = await puppeteer.launch(this.options)
}
public async getPage(url: string): Promise<Page> {
if (!this.browser) {
throw new Error('Browser must init first')
}
if (this.pages[url]) {
return this.pages[url];
}
const page = await this.browser.newPage();
await page.goto(url)
this.pages[url] = page;
return page;
}
2023-06-04 14:14:28 +09:00
public async close() {
this.browser?.close();
}
2023-05-12 18:16:25 +09:00
}
class FreeBrowserPool {
private size: number = 0;
private readonly pool: FreeBrowser[];
2023-06-04 14:14:28 +09:00
private debug: boolean = false;
2023-05-12 18:16:25 +09:00
constructor() {
this.pool = [];
}
2023-06-05 17:00:29 +09:00
public async init(size: number, debug: boolean) {
2023-06-04 14:14:28 +09:00
this.debug = debug;
2023-05-12 18:16:25 +09:00
console.log(`browser pool init size:${size}`)
if (!fs.existsSync(runPath)) {
fs.mkdirSync(runPath);
}
this.size = size;
for (let i = 0; i < size; i++) {
2023-06-04 14:14:28 +09:00
this.pool.push(await this.newBrowser());
2023-05-12 18:16:25 +09:00
}
}
public getRandom(): FreeBrowser {
return this.pool[Math.floor(Math.random() * this.pool.length)]
}
2023-06-04 14:14:28 +09:00
private async newBrowser(): Promise<FreeBrowser> {
const options: PuppeteerLaunchOptions = {
2023-06-05 12:08:47 +09:00
headless: this.debug ? false : 'new',
2023-06-05 17:00:29 +09:00
args: ['--no-sandbox']
2023-06-04 14:14:28 +09:00
};
2023-06-05 17:00:29 +09:00
if (process.env.http_proxy) {
options.args?.push(`--proxy-server=${process.env.http_proxy}`);
}
2023-06-04 14:14:28 +09:00
const browser = new FreeBrowser(v4(), options);
await browser.init();
return browser;
}
public async remove(id: string) {
let removed = false;
this.pool.filter(item => {
if (item.id === id) {
item.close();
removed = true;
return false;
}
return true;
})
if (removed) {
this.pool.push(await this.newBrowser());
}
}
2023-05-12 18:16:25 +09:00
}
export const freeBrowserPool = new FreeBrowserPool();