Skip to main content
Glama
screenshot.ts3.97 kB
import puppeteer from 'puppeteer-core' import * as ChromeLauncher from 'chrome-launcher' /** * 截图服务类,用于对指定URL进行网页截图 */ export class ScreenshotService { constructor() { } /** * 获取Chrome可执行文件路径 * @returns Chrome路径 */ private async getChromeExecutablePath(): Promise<string> { try { // 使用 chrome-launcher 自动查找 Chrome const installation = await ChromeLauncher.Launcher.getInstallations() if (installation && installation.length > 0) { return installation[0] // 返回第一个找到的 Chrome 安装路径 } } catch (error) { console.warn('Chrome launcher failed to find Chrome installation:', error) } // 如果 chrome-launcher 失败,回退到手动路径 const platform = process.platform if (platform === 'darwin') { // macOS return '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' } else if (platform === 'win32') { // Windows return 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe' } else { // Linux return '/usr/bin/google-chrome' } } /** * 对指定URL进行截图 * @param url 要截图的URL * @param options 截图选项 * @param options.fileName 截图文件名称 * @param options.fullPage 是否截取全页面 * @param options.width 截图宽度 * @param options.height 截图高度 * @param options.timeout 超时时间(毫秒) * @returns 截图ImageBuffer */ async takeScreenshot(url: string, options?: { fileName?: string fullPage?: boolean width?: number height?: number timeout?: number }) { const browser = await puppeteer.launch({ headless: true, executablePath: await this.getChromeExecutablePath(), args: ['--no-sandbox', '--disable-setuid-sandbox'] }) try { // 创建新页面 const page = await browser.newPage() // 设置视口大小 await page.setViewport({ width: 375, height: 0, }) // 导航到指定URL,等待网络空闲 await page.goto(url, { timeout: options?.timeout || 30000, waitUntil: 'networkidle0', }) // 执行截图 const imageBuffer = await page.screenshot({ fullPage: options?.fullPage || false, }) // 将 Uint8Array 转换为 Buffer const buffer = Buffer.from(imageBuffer) // const imageBufferStr = buffer.toString('base64') // console.log('imageBufferStr', imageBufferStr) return buffer } finally { // 确保浏览器关闭 await browser.close() } } /** * 对指定元素进行截图 * @param url 要截图的URL * @param selector 元素选择器 * @param options 截图选项 * @param options.fileName 截图文件名称 * @param options.timeout 超时时间(毫秒) * @returns 截图ImageBuffer */ async takeElementScreenshot(url: string, selector: string, options?: { fileName?: string timeout?: number }) { const browser = await puppeteer.launch({ headless: true, executablePath: await this.getChromeExecutablePath(), args: ['--no-sandbox', '--disable-setuid-sandbox'] }) try { const page = await browser.newPage() await page.goto(url, { timeout: options?.timeout || 30000, waitUntil: 'networkidle0', }) // 等待选择器对应的元素出现 await page.waitForSelector(selector, { timeout: options?.timeout || 30000 }) // 对指定元素进行截图 const element = await page.$(selector) if (!element) { throw new Error(`Element with selector "${selector}" not found`) } const imageBuffer = await element.screenshot() // 将 Uint8Array 转换为 Buffer const buffer = Buffer.from(imageBuffer) return buffer } finally { await browser.close() } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Panzer-Jack/feuse-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server