UNPKG

puppeteer-browser-agent

Version:
108 lines (90 loc) 2.76 kB
import type { PuppeteerLifeCycleEvent } from "puppeteer"; import type { IDriverAction } from "../base-action"; import type { DebugOpts } from "../../../../types"; import { ElementAction } from "../element-action"; import { type ISearchResult, PresearchAdapter, type ISearchEngineAdapter, } from "./presearch-adapter"; export interface ISearchAction extends IDriverAction {} export type QueryFn = (query: string) => string; export type SearchOpts = DebugOpts & {}; export type SearchEngineRegistry = Record<string, QueryFn>; export class SearchAction extends ElementAction implements ISearchAction { waitUntil: PuppeteerLifeCycleEvent = "load"; name = "search"; defaultEngine = "presearch"; searchEngines: SearchEngineRegistry = { google: (query: string) => `https://google.com/search?q=${query}`, presearch: (query: string) => `https://presearch.com/search?q=${query}`, bing: (query: string) => `https://www.bing.com/search?q${query}`, }; searchResults?: ISearchResult[] = []; adapters: Record<string, ISearchEngineAdapter> = {}; registerDefaultAdapters() { if (!this.page) { return; } const presearch = new PresearchAdapter(this.page); this.registerAdapter("presearch", presearch); } registerAdapter(key: string, adapter: ISearchEngineAdapter) { this.adapters[key] = adapter; } get query() { return this.fnArgs.query; } get searchEngineName() { const name = this.fnArgs.searchEngine; return name ? name.toLowerCase() : this.defaultEngine; } get searchEngine(): QueryFn | undefined { return this.searchEngines[this.searchEngineName]; } get adapter() { return this.adapters[this.searchEngineName]; } get queryUrl() { if (!this.searchEngine) { throw new Error("Invalid search engine configuration"); } return this.searchEngine(this.query); } onStart() { this.logTask(`Searching ${this.searchEngineName} for ${this.query}`); } async execute() { this.onStart(); if (!this.page) { throw new Error("Missing page"); } try { await this.gotoUrl(this.queryUrl); } catch (error: any) { this.setMessage( `Error searching with ${this.queryUrl}: ${error.message}`, ); } this.onStartScraping(); const searchResults = await this.getSearchResults(); this.addToMessage(`search results found: ${JSON.stringify(searchResults)}`); this.searchResults = searchResults; } async gotoUrl(url: string) { const { waitUntil } = this; await this.page?.goto(url, { waitUntil, }); } onStartScraping() { this.logTask("Scraping page..."); } protected async getSearchResults() { if (!this.page) { throw new Error("Missing page"); } return await this.adapter?.getSearchResults(); // return await this.elementSelector?.getSearchResults(this.page); } }