Skip to content

Playwright系列教程(一)网页截图

更新时间: at 14:28

Playwright 官网是这样介绍自己的 —— “为现代web 应用提供了可靠的端到端的测试能力。”

总结一下就是只要是跑在浏览器上的web应用(网页)我都能跑,你写代码告诉我,我就能自己跑~

听上去是不是很酷,接下来我们就亲手写一个自动截图网页的 Palywright 应用。

初始化项目

  1. 新建一个文件夹取名为 playwright-screenshot
  2. 使用命令初始化 npm init -y
  3. 安装依赖 npm install playwright --save-dev

修改 package.json

添加 start 启动命令

{
  "name": "playwright-screenshot",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "start": "node index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "playwright": "^1.49.0"
  }
}

创建 index.js

import { chromium } from "playwright";
import fs from "fs";
import path from "path";

async function takeScreenshot(url) {
  const browser = await chromium.launch();
  const page = await browser.newPage();

  try {
    await page.goto(url);
    await page.waitForLoadState("networkidle");

    const title = await page.title();

    const description = await page
      .$eval('meta[name="description"]', el => el.content)
      .catch(() => "No description available");

    const folderName = new URL(url).hostname;
    const folderPath = path.join(process.cwd(), folderName);

    if (!fs.existsSync(folderPath)) {
      fs.mkdirSync(folderPath, { recursive: true });
    }

    const screenshotPath = path.join(
      folderPath,
      `screenshot-${new Date().toISOString().replace(/[:.]/g, "-")}.png`
    );
    await page.screenshot({
      path: screenshotPath,
      fullPage: true,
    });

    const metadata = {
      url,
      title,
      description,
      capturedAt: new Date().toISOString(),
    };

    fs.writeFileSync(
      path.join(folderPath, "site.json"),
      JSON.stringify(metadata, null, 2)
    );

    console.log("Screenshot and metadata saved successfully!");
    console.log(`Folder: ${folderPath}`);
  } catch (error) {
    console.error("Error:", error);
  } finally {
    await browser.close();
  }
}

const url = process.argv[2] || "https://example.com";
takeScreenshot(url).catch(console.error);

这就完事了~整个代码其实不多,我们来逐行分析下。

顶部是基础的库引入,然后创建了一个 takeScreenshot 函数,我们一会来分析这个函数干了什么事情。

之后我们从运行的参数中获取 url,然后传递给了 takeScreenshot 并调用。

takeScreenshot

这个函数接受一个 url 作为入参,也就是我们打算访问并截图的网址。

函数先是创建了一个浏览器实例 const browser = await chromium.launch() 然后创建了一个新的页面 const page = await browser.newPage() 然后访问网址 await page.goto(url) 等待页面加载完成 await page.waitForLoadState('networkidle') 然后获取网页的标题,描述

const title = await page.title();

const description = await page
  .$eval('meta[name="description"]', el => el.content)
  .catch(() => "No description available");

之后就是最关键的 API 了截图

await page.screenshot({
  path: screenshotPath,
  fullPage: true,
});

是不是“炒鸡”简单,基本上都是语义化的api调用,之后你就保存你想要的东西到本地,或者数据库都行,一个简单的自动截图工具就完事了~

github源码