给自己的网站截图

2024-06-19 • ☕️ 6 min read

皮尤研究中心的一项新分析表明:2013 年存在的网页中有 38% 目前无法访问。可见互联网上的内容实际上是多么短暂。不管你的内容是托管在第三方平台或者自己架设的 nas 上面,都面临着可能的数据丢失或无法访问的风险。

为了应对这些风险,以尽可能低的成本争取尽可能多的备份是一个明智的策略。以往我的大多数保存工作的重点是保存内容,但我经常看到一些记录时间推移中人物变化的图片组合。这些包含时间的图片组合往往给我带来比较大的冲击力。

有时经常大刀阔斧对博客进行外观的改造,以致于后来忘记了博客之前的外观。虽然说也问题不大,但是对于我这种比较怀旧的人来说,可能以后会想回顾以下。

所以我为何不把网站的外观变化也记录下来呢?

如何截图

说做就做,如果要把网站外观记录下来,那么直接手动对网站进行截图然后再保存在某个地方,无疑是最快速的方法。

但是这对程序员来说是不可接受的重复劳动,所以问题变成如何以编程方式现给网站进行截图?

答案是可以使用 Playwright 来对网站进行截图。Playwright 是一个用于自动化测试 Web 浏览器的库。你可以使用它在 Chromium 中打开网站、单击按钮、检查页面加载是否正确等等。

它的最直接的使用方式如下所示:

# 安装 Playwright 库
npm install playwright
 
# 使用 Playwright 安装 Chromium 浏览器
npx playwright install chromium
 
# 使用 Playwright 对指定的网站进行全页面截图,并保存为 screenshot.png
npx playwright screenshot --full-page "blog.codeep.xyz" "screenshot.png"
 

这会安装 Playwright,然后在 Chromium 中打开我的网站并截取页面的屏幕截图。 --full-page 标志确保图像包含整个可滚动页面,就好像你有一个高屏幕并且可以在不滚动的情况下容纳整个页面。

定期执行

一旦我知道如何截取一次屏幕截图,我就想定期对网站进行截屏,并将这些图像保存在某个地方。

我决定使用 GitHub Actions,因为它是免费的并且集成了 GitHub 仓库。这样,我不但可以自动化截图的过程,还可以将截图存储在与我的代码库相同的地方,便于管理和访问。

要在 GitHub Actions 中设置自动截图,首先需要创建一个新的工作流文件。而我用于屏幕截图的代码完全包含在单个 GitHub Actions 工作流程中。它位于一个名为 .github/workflows/take_screenshots.yml 的文件中。你也可以在项目的 .github/workflows 目录下创建一个 YAML 文件,如下所示:

name: Take screenshots
 
on:
  push:
    branches:
      - main
  schedule:
    - cron: '7 7 * * 1' # 每周一的 UTC 时间 7:07 分自动执行
 
jobs:
  take-screenshots:
    runs-on: macos-latest
    strategy:
      matrix:
        include:
          - url: blog.codeep.xyz # 截图的网站 URL 
            filename_prefix: codeep.xyz # 文件名前缀
      max-parallel: 1 
 
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          ref: main
          lfs: false
      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
      - name: Install Playwright and browser
        run: |
          npm install playwright
          npx playwright install chromium
      - name: Take screenshot
        run: |
          today=$(date +"%Y-%m-%d")
          screenshot_path="screenshots/${{ matrix.filename_prefix }}.$today.png"
 
          # Make these variables available to subsequent steps
          # See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable
          echo "today=$today" >> "$GITHUB_ENV"
          echo "screenshot_path=$screenshot_path" >> "$GITHUB_ENV"
 
          mkdir -p "$(dirname "$screenshot_path")"
 
          # If there's already a screenshot for today, don't
          # bother overwriting it.
          if [[ -f "$screenshot_path" ]]; then exit 0; fi
 
          npx playwright screenshot \
            --full-page \
            --wait-for-timeout 10000 \
            "${{ matrix.url }}" "$screenshot_path"
      - name: Push changes to GitHub
        run: |
          git add "$screenshot_path"
          git commit -m "Add screenshot for ${{ matrix.url }} for $today" || exit 0
          git push origin main
 

工作流有两种触发条件:

  • 当有代码推送到 main 分支时。
  • 根据 cron 表达式,每周一的 UTC 时间 7:07 分自动执行。

它安装了 Playwright,并使用它来截取网站的屏幕截图:blog.codeep.xyz(本网站)。图像保存在名为 screenshots 的文件夹中,文件名包括站点名称和拍摄日期,例如 codeep.xyz.2024-06-19.png。

复制上面的 yaml 内容到自己项目中后,修改 matrix 部分(上面高亮位置)为自己想获取的网站的屏幕截图。

创建屏幕截图后,它会提交到 Git 并推送到 GitHub。记住必须调整 GITHUB_TOKEN 权限以允许 GitHub Actions 将提交推送到存储库。

长期备份

定期截图是一种很好的实时数据备份方法,但考虑到数据的长期保存,可能还需要其他的备份策略。例如,你可以定期将这些截图存储到云存储服务。这不仅可以减少本地数据损失的风险,还可以利用这些服务的持久性和冗余功能来增强数据安全性。

开始定期对网站进行屏幕截图的最佳时间是在注册域名时,第二个最好的时间就是现在。