截取屏幕截图

要截取网页屏幕截图并将其写入 datasette-io.png,运行此命令:

shot-scraper https://datasette.com.cn/

如果文件 datasette-io.png 已存在,则将改用文件名 datasette-io.1.png

您可以使用 -o 选项指定文件名

shot-scraper https://datasette.com.cn/ -o datasette.png

使用 -o - 将 PNG 图像写入标准输出

shot-scraper https://datasette.com.cn/ -o - > datasette.png

如果省略协议,http:// 将自动添加,并会遵循任何重定向

shot-scraper datasette.io -o datasette.png

调整浏览器宽度和高度

用于截取屏幕截图的浏览器窗口默认为宽 1280px,高 780px。

您可以使用 --width--height 选项(简称 -w-h)调整这些值

shot-scraper https://datasette.com.cn/ -o small.png --width 400 --height 800

如果同时提供这两个选项,则生成的屏幕截图将是该尺寸。如果省略 --height,则会生成全页长屏幕截图(默认)。

使用 CSS 选择器截取特定区域

要截取页面上特定元素的屏幕截图,请使用 --selector-s 及其 CSS 选择器

shot-scraper https://simonwillison.net/ -s '#bighead'

这将生成包含此图像的 simonwillison-net.png

Just the header section from my blog

使用 --selector 时,如果提供了高度和宽度,它们将设置页面加载时浏览器窗口的大小,但生成的屏幕截图仍将与页面上的元素具有相同的尺寸。

您可以多次传递 --selector。生成的屏幕截图将覆盖包含您指定的所有元素的页面最小区域,例如

shot-scraper https://simonwillison.net/ \
  -s '#bighead' -s .overband \
  -o bighead-multi-selector.png

要捕获与 CSS 选择器匹配的每个元素周围的矩形,请使用 --selector-all

shot-scraper https://simonwillison.net/ \
  --selector-all '.day' \
  -o just-the-day-boxes.png

您可以添加 --padding 20 以在截屏时在元素周围添加 20px 的内边距。

使用 JavaScript 过滤器指定元素

--js-selector--js-selector-all 选项可用于使用 JavaScript 表达式来选择仅使用 CSS 选择器无法定位的元素。

这些选项应传递操作 el 变量的 JavaScript 表达式,如果该元素应包含在屏幕截图选择中,则返回 true

要截取页面上包含文本“shot-scraper”的第一个段落的屏幕截图,您可以运行以下命令

shot-scraper https://github.com/simonw/shot-scraper \
  --js-selector 'el.tagName == "P" && el.innerText.includes("shot-scraper")'

这里需要 el.tagName == "P" 部分,否则页面上的 <html> 元素将是第一个匹配表达式的。

将在页面上执行的生成的 JavaScript 如下所示

Array.from(document.getElementsByTagName('*')).find(
  el => el.tagName == "P" && el.innerText.includes("shot-scraper")
).classList.add("js-selector-a1f5ba0fc4a4317e58a3bd11a0f16b96");

--js-selector-all 选项将选择所有匹配的元素,类似于上面描述的 --selector-all 选项。

等待延迟

有时,页面在截取屏幕截图之前可能尚未完全加载。您可以使用 --wait X 在页面加载事件触发后等待指定的毫秒数,然后再截取屏幕截图

shot-scraper https://simonwillison.net/ --wait 2000

等待直到特定条件

除了等待特定时间外,您还可以使用 --wait-for expression 选项等待直到 JavaScript 表达式返回 true。

此示例在 ID 为 content<div> 在 DOM 中可用时立即截取屏幕截图

shot-scraper https://.../ \
  --wait-for 'document.querySelector("div#content")'

这里有一个示例,它等待特定元素可用(在本例中为 cookie 同意叠加层),然后在截取屏幕截图之前将其删除

shot-scraper -h 800 'https://www.spiegel.de/international/' \
  --wait-for "() => {
    const div = document.querySelector('[id^="sp_message_container"]');
    if (div) {
      div.remove();
      return true;
    }
  }"

如果表达式解析时间超过 30 秒,shot-scraper 将会出错退出。

执行自定义 JavaScript

您可以使用自定义 JavaScript 在页面加载后(在“onload”事件触发后)但在截取屏幕截图之前修改页面,使用 --javascript 选项

shot-scraper https://simonwillison.net/ \
  -o simonwillison-pink.png \
  --javascript "document.body.style.backgroundColor = 'pink';"

使用 JPEG 代替 PNG

屏幕截图默认为 PNG。您可以通过指定以 .jpg 结尾的 -o 文件名来另存为 JPEG。

您还可以使用 --quality X 以指定的质量保存为 JPEG,以减小文件大小。这里使用 80 是一个不错的数值

shot-scraper https://simonwillison.net/ \
  -h 800 -o simonwillison.jpg --quality 80
% ls -lah simonwillison.jpg
-rw-r--r--@ 1 simon  staff   168K Mar  9 13:53 simonwillison.jpg

设备缩放因子

--scale-factor 选项设置特定的设备缩放因子,这有效地模拟了不同的设备像素比。此设置对于测试高分辨率显示器或模拟具有不同像素密度的屏幕很有用。

例如,设置 --scale-factor 3 会生成 CSS 像素比为 3 的图像,这非常适合模拟高分辨率显示器,例如 Apple iPhone 12 屏幕。

要以 3 的缩放因子(分辨率提高三倍)截取屏幕截图,请运行以下命令

shot-scraper https://simonwillison.net/ -o simon.png \
  --width 390 --height 844 --scale-factor 3

这会将屏幕截图的宽度和高度都乘以 3,生成宽度为 1170px、高度为 2532px 的图像,与 iPhone 12 的屏幕相匹配。

--scale-factor 选项接受正浮点数作为输入。例如,设置 --scale-factor 2.625 可模拟 Google Pixel 6 的 CSS 像素比。

Retina 图像

--retina 选项是设置设备缩放因子为 2 的快捷方式。这意味着图像的分辨率将有效翻倍,模拟在 Retina 或更高像素密度屏幕上显示图像。

shot-scraper https://simonwillison.net/ -o simon.png \
  --width 400 --height 600 --retina

此示例将生成宽度为 800px、高度为 1200px 的图像。

注意:--retina 选项不应与 --scale-factor 标志一起使用,因为它们互斥。如果同时提供两者,命令将引发错误以防止冲突。

透明背景

--omit-background 选项指示浏览器忽略默认背景,从而允许捕获具有透明背景的页面。不适用于 JPG 图像或设置了 quality 时。

shot-scraper https://simonwillison.net/ -o simon.png \
  --width 400 --height 600 --omit-background

与页面交互

有时,能够在捕获屏幕截图之前手动与页面交互很有用。

添加 --interactive 选项以打开一个可交互的浏览器窗口。然后,当您准备好截屏并关闭窗口时,在终端中按 <enter>

shot-scraper https://simonwillison.net/ -o after-interaction.png \
  --height 800 --interactive

这将输出

Hit <enter> to take the shot and close the browser window:
  # And after you hit <enter>...
Screenshot of 'https://simonwillison.net/' written to 'after-interaction.png'

记录所有请求

有时查看浏览器在渲染页面时发出的所有请求列表很有用。

使用 --log-requests 输出以换行符分隔的 JSON,表示每个请求,包括图像和其他资源的请求。

传递 - 将列表输出到标准输出,或使用文件名写入磁盘文件。

输出如下所示

shot-scraper https://datasette.com.cn/ --log-requests -
{"method": "GET", "url": "https://datasette.com.cn/", "status": 302, "size": null, "timing": {"startTime": 1663211674984.7068, "domainLookupStart": 0.698, "domainLookupEnd": 1.897, "connectStart": 1.897, "secureConnectionStart": -1, "connectEnd": 18.726, "requestStart": 18.86, "responseStart": 99.75, "responseEnd": 101.75000000162981}}
{"method": "GET", "url": "https://datasette.com.cn/", "status": 200, "size": 34592, "timing": {"startTime": 1663211675085.51, "domainLookupStart": 0.187, "domainLookupEnd": 0.197, "connectStart": 0.197, "secureConnectionStart": 15.719, "connectEnd": 63.854, "requestStart": 64.098, "responseStart": 390.231, "responseEnd": 399.268}}
{"method": "GET", "url": "https://datasette.com.cn/static/site.css", "status": 200, "size": 3952, "timing": {"startTime": 1663211675486.027, "domainLookupStart": -1, "domainLookupEnd": -1, "connectStart": -1, "secureConnectionStart": -1, "connectEnd": -1, "requestStart": 0.408, "responseStart": 99.407, "responseEnd": 100.433}}
...

请注意,这里的 size 字段将是响应的字节大小,但在某些情况下此信息不可用,将返回为 "size": null

浏览器参数

传递给浏览器实例的其他参数。Chromium 标志列表可以在此处找到。

例如,要移除字体渲染提示

shot-scraper https://simonwillison.net/ -o no-hinting.png \
  --height 800 --browser-arg "--font-render-hinting=none"

要添加多个参数,为每个参数添加 --browser-arg

shot-scraper https://simonwillison.net/ -o no-hinting-no-gpu.png \
  --height 800 --browser-arg "--font-render-hinting=none" --browser-arg "--disable-gpu"

截取本地 HTML 文件屏幕截图

您可以将磁盘上的 HTML 文件路径传递给它,以截取该渲染文件的屏幕截图

shot-scraper index.html -o index.png

使用相对路径从该文件中引用的 CSS 和图像也将包含在内。

执行 JavaScript 的技巧

如果您使用 --javascript 选项执行代码,则该代码将在页面加载事件触发后但在截取屏幕截图之前执行。

您可以使用该代码执行隐藏或删除特定页面元素、单击链接打开菜单,甚至在页面上添加注释等操作,例如此粉色箭头示例

此代码将隐藏所有具有 [data-ad-rendered] 属性的元素以及 ID 为 id="ensNotifyBanner" 的元素

document.querySelectorAll(
    '[data-ad-rendered],#ensNotifyBanner'
).forEach(el => el.style.display = 'none')

您可以按如下方式执行

shot-scraper https://www.latimes.com/ -o latimes.png --javascript "
document.querySelectorAll(
    '[data-ad-rendered],#ensNotifyBanner'
).forEach(el => el.style.display = 'none')
"

在某些情况下,您可能需要在截取屏幕截图之前在自定义 JavaScript 执行期间添加暂停 - 例如,如果您单击触发短暂淡入淡出动画的按钮。

您可以使用以下模式执行此操作

new Promise(takeShot => {
  // Your code goes here
  // ...
  setTimeout(() => {
    // Resolving the promise takes the shot
    takeShot();
  }, 1000);
});

如果您的自定义代码定义了一个 Promiseshot-scraper 将等待该 Promise 完成后才截取屏幕截图。在这里,屏幕截图直到调用 takeShot() 函数时才会发生。

如果您看到与 CSP 标头相关的错误,例如“Failed to fetch dynamically imported module”,您可以使用--bypass-csp 选项解决它们。

查看 console.log() 输出

几乎所有 shot-scraper 命令都接受 --log-console 选项,这将使它们在命令运行时将任何 console.log() 调用输出到标准错误。

这包括现有页面 JavaScript 中的 console.log() 调用,以及您自己自定义 JavaScript 中包含的对该方法的任何调用。

例如,在截取 Facebook 主页的屏幕截图时运行 --log-console 将显示此警告消息,这是 Facebook 记录到开发者工具控制台以帮助保护人们免受社会工程攻击的信息

% shot-scraper shot facebook.com --log-console

 .d8888b.  888                       888
d88P  Y88b 888                       888
Y88b.      888                       888    This is a browser feature intended for
 "Y888b.   888888  .d88b.  88888b.   888    developers. If someone told you to copy-paste
    "Y88b. 888    d88""88b 888 "88b  888    something here to enable a Facebook feature
      "888 888    888  888 888  888  Y8P    or "hack" someone's account, it is a
Y88b  d88P Y88b.  Y88..88P 888 d88P         scam and will give them access to your
 "Y8888P"   "Y888  "Y88P"  88888P"   888    Facebook account.
                           888
                           888
                           888

See https://www.facebook.com/selfxss for more information.

Screenshot of 'http://facebook.com' written to 'facebook-com.png'

shot-scraper shot --help

此命令的完整 --help

Usage: shot-scraper shot [OPTIONS] URL

  Take a single screenshot of a page or portion of a page.

  Usage:

      shot-scraper www.example.com

  This will write the screenshot to www-example-com.png

  Use "-o" to write to a specific file:

      shot-scraper https://www.example.com/ -o example.png

  You can also pass a path to a local file on disk:

      shot-scraper index.html -o index.png

  Using "-o -" will output to standard out:

      shot-scraper https://www.example.com/ -o - > example.png

  Use -s to take a screenshot of one area of the page, identified using one or
  more CSS selectors:

      shot-scraper https://simonwillison.net -s '#bighead'

Options:
  -a, --auth FILENAME             Path to JSON authentication context file
  -w, --width INTEGER             Width of browser window, defaults to 1280
  -h, --height INTEGER            Height of browser window and shot - defaults
                                  to the full height of the page
  -o, --output FILE
  -s, --selector TEXT             Take shot of first element matching this CSS
                                  selector
  --selector-all TEXT             Take shot of all elements matching this CSS
                                  selector
  --js-selector TEXT              Take shot of first element matching this JS
                                  (el) expression
  --js-selector-all TEXT          Take shot of all elements matching this JS
                                  (el) expression
  -p, --padding INTEGER           When using selectors, add this much padding in
                                  pixels
  -j, --javascript TEXT           Execute this JS prior to taking the shot
  --scale-factor FLOAT            Device scale factor. Cannot be used together
                                  with '--retina'.
  --retina                        Use device scale factor of 2. Cannot be used
                                  together with '--scale-factor'.
  --omit-background               Omit the default browser background from the
                                  shot, making it possible take advantage of
                                  transparency. Does not work with JPEGs or when
                                  using --quality.
  --quality INTEGER               Save as JPEG with this quality, e.g. 80
  --wait INTEGER                  Wait this many milliseconds before taking the
                                  screenshot
  --wait-for TEXT                 Wait until this JS expression returns true
  --timeout INTEGER               Wait this many milliseconds before failing
  -i, --interactive               Interact with the page in a browser before
                                  taking the shot
  --devtools                      Interact mode with developer tools
  --log-requests FILENAME         Log details of all requests to this file
  --log-console                   Write console.log() to stderr
  -b, --browser [chromium|firefox|webkit|chrome|chrome-beta]
                                  Which browser to use
  --browser-arg TEXT              Additional arguments to pass to the browser
  --user-agent TEXT               User-Agent header to use
  --reduced-motion                Emulate 'prefers-reduced-motion' media feature
  --fail                          Fail with an error code if a page returns an
                                  HTTP error
  --skip                          Skip pages that return HTTP errors
  --bypass-csp                    Bypass Content-Security-Policy
  --silent                        Do not output any messages
  --auth-password TEXT            Password for HTTP Basic authentication
  --auth-username TEXT            Username for HTTP Basic authentication
  --help                          Show this message and exit.