平台

设备仿真指南:移动、平板和桌面配置文件

如何仿真完整的设备身份,包括触摸事件、屏幕指标和移动 UA,以实现真实的移动和桌面配置文件。

文档中心

想直接看维护中的产品文档?

这篇文章对应的主题已经有文档中心页面。需要规范流程、当前参数和长期参考时,优先看 docs。

简介

浏览器通过数十个信号揭示其设备:屏幕尺寸、设备像素比、触摸能力、设备内存、GPU 特征、输入模态等。这些信号形成了运行浏览器的物理设备的完整画面。Pixel 7 有特定的屏幕尺寸、特定的 DPR、特定数量的触摸点、特定的 GPU 和特定的内存。当这些信号一致时,浏览器看起来运行在真实硬件上。当它们冲突时,不一致就是可见的。

BotBrowser 加载从真实硬件采集的完整设备配置文件。当在桌面系统上加载移动配置文件时,所有设备信号一致更新,因为它们都来自同一源设备。没有混合搭配、没有手动配置单个属性、也没有信号冲突的风险。

隐私影响:为什么设备信号很重要

设备仿真的重要性不仅在于呈现为移动或桌面浏览器。

追踪系统将设备信号作为其指纹过程的一部分。屏幕分辨率、DPR、触摸支持、设备内存、GPU 渲染器和 CPU 核心数的组合创建了跨会话持久的设备级指纹。控制这些信号对于维护一致的浏览器身份和研究追踪系统如何使用设备特征都是必要的。

电商和内容平台根据检测到的设备提供不同的体验。移动用户可能看到不同的定价、不同的布局和不同的内容选择。隐私研究人员需要设备准确的仿真来可靠地研究这些做法。

对于多账户管理,设备多样性很重要。让每个身份都呈现为具有相同屏幕尺寸的相同设备型号是可疑的。使用多种设备配置文件,混合桌面和移动,不同的屏幕尺寸和不同的 DPR 值,可以创建自然的变化。

技术背景

浏览器中的设备信号

浏览器通过多个 API 暴露设备特征:

屏幕尺寸screen.widthscreen.heightscreen.availWidthscreen.availHeight 报告物理显示大小。window.innerWidthwindow.innerHeight 报告视口。window.outerWidthwindow.outerHeight 包含浏览器边框。

设备像素比window.devicePixelRatio 报告 CSS 像素和物理像素之间的比率。桌面显示器通常 DPR 为 1.0 或 1.25。移动设备范围从 2.0 到 3.5 或更高。Retina MacBook 报告 2.0。

触摸能力navigator.maxTouchPoints 报告最大同时触摸点数(桌面为 0,移动为 5-10)。window 对象上的 ontouchstart 事件处理程序可用性指示触摸支持。CSS 媒体查询 (pointer: coarse)(hover: none) 区分以触摸为主和以指针为主的输入。

设备内存navigator.deviceMemory 报告近似 RAM(单位 GB)。移动设备通常报告 4-8 GB,桌面 8-16 GB。

硬件并发性navigator.hardwareConcurrency 报告可用 CPU 核心数。移动设备通常报告 4-8,桌面 4-16 或更多。

连接信息navigator.connection 提供网络类型、有效类型、下行速度和 RTT。移动设备通常报告与桌面系统不同的网络特征。

GPU:WebGL 渲染器字符串标识图形硬件。移动 GPU(Adreno、Mali、PowerVR、Apple GPU)与桌面 GPU(NVIDIA GeForce、AMD Radeon、Intel UHD)完全不同。

信号一致性要求

这些信号必须内部一致。一个报告 maxTouchPoints: 10 但同时报告 (pointer: fine)(hover: hover) 的浏览器包含矛盾。一个具有 412px 屏幕宽度但 16 GB 设备内存和 NVIDIA GPU 的浏览器混合了移动屏幕尺寸和桌面硬件特征。这些不一致表明各个信号是伪造的,而非来自真实设备。

常见方案及其局限性

Chrome DevTools 设备仿真

Chrome DevTools Protocol 通过 Emulation.setDeviceMetricsOverride 提供设备仿真。这设置了视口尺寸、DPR 和触摸支持。Playwright 和 Puppeteer 通过其设备仿真 API 暴露此功能。

局限性:

  • 不改变 navigator.platform 或超出显式设置范围的 User-Agent 数据
  • WebGL 渲染器字符串仍报告桌面 GPU
  • navigator.deviceMemorynavigator.hardwareConcurrency 保持桌面值
  • 触摸仿真是表面级的,不是引擎级的
  • 字体可用性仍是桌面特定的
  • 媒体查询可能不完全与仿真设备对齐

手动属性覆盖

你可以通过 JavaScript 注入覆盖单个属性:

Object.defineProperty(navigator, 'maxTouchPoints', { get: () => 10 });
Object.defineProperty(navigator, 'deviceMemory', { get: () => 4 });

这改变了 JavaScript 可见的值,但不影响浏览器的实际行为。CSS 媒体查询、渲染管线行为和 HTTP 头不受 JavaScript 属性覆盖的影响。

仅视口方案

通过自动化框架设置移动视口大小(例如 412x915)改变了布局,但不改变任何其他设备信号。浏览器仍报告桌面屏幕尺寸、桌面 DPR、零触摸点和桌面 GPU 信息。

BotBrowser 的方案

BotBrowser 配置文件从真实设备采集,意味着所有设备信号来自同一物理硬件。当加载到任何系统上时,这些信号在引擎级别作为整体应用,确保完整的内部一致性。

基于配置文件的设备身份

每个配置文件包含设备特征的快照:

  • 屏幕尺寸(宽度、高度、可用宽度、可用高度)
  • 设备像素比
  • 触摸能力(maxTouchPoints、触摸事件支持)
  • 设备内存
  • 硬件并发性
  • GPU 渲染器和供应商字符串
  • 平台特定的 navigator 属性
  • 窗口边框尺寸(用于计算外部尺寸)

所有这些信号作为整体应用,而非单独应用。这消除了信号冲突的风险。

引擎级触摸支持

当加载移动配置文件时,触摸支持在 Chromium 引擎级别启用,而非通过 JavaScript 注入:

  • navigator.maxTouchPoints 返回设备的实际值
  • ontouchstart 在 window 对象上原生可用
  • CSS 媒体查询 (pointer: coarse)(hover: none) 在样式引擎中正确评估
  • 触摸事件构造函数和属性的行为与真实设备完全一致
  • InputDeviceCapabilities API 正确报告触摸

桌面、移动和平板配置文件

BotBrowser 支持来自所有设备类别的配置文件:

桌面配置文件:大屏幕(1920x1080、2560x1440),DPR 1.0-2.0,零触摸点,精细指针,桌面 GPU,8-16 GB 内存。

移动配置文件:小屏幕(412x915、390x844),DPR 2.0-3.5,触摸支持带 5-10 个点,粗略指针,移动 GPU,4-8 GB 内存。

平板配置文件:中等屏幕(1024x1366、820x1180),DPR 2.0,触摸支持,有时同时具有粗略和精细指针,移动或集成 GPU。

窗口和屏幕配置

BotBrowser 通过 CLI 标志提供对窗口和屏幕属性的细粒度控制:

# 使用配置文件采集的尺寸(headless 默认)
--bot-config-window=profile
--bot-config-screen=profile

# 特定尺寸
--bot-config-window=1920x1080
--bot-config-screen=2560x1440

# 完整 JSON 自定义
--bot-config-window='{"innerWidth":1920,"innerHeight":1080,"devicePixelRatio":2}'

配置和用法

移动设备配置文件

chrome --bot-profile="/profiles/pixel7-chrome-130.enc" \
       --user-data-dir="$(mktemp -d)"

Playwright 集成

const { chromium } = require('playwright-core');

(async () => {
  const browser = await chromium.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/profiles/pixel7-chrome-130.enc',
    ],
    headless: true,
  });

  // 重要:不要设置视口 - 让配置文件控制
  const context = await browser.newContext();
  const page = await context.newPage();

  const metrics = await page.evaluate(() => ({
    screenWidth: screen.width,
    screenHeight: screen.height,
    innerWidth: window.innerWidth,
    innerHeight: window.innerHeight,
    dpr: devicePixelRatio,
    touchPoints: navigator.maxTouchPoints,
    touchStart: 'ontouchstart' in window,
    pointer: matchMedia('(pointer: coarse)').matches ? 'coarse' : 'fine',
    hover: matchMedia('(hover: none)').matches ? 'none' : 'hover',
    memory: navigator.deviceMemory,
    cores: navigator.hardwareConcurrency,
  }));

  console.log('Device metrics:', metrics);
  await browser.close();
})();

Puppeteer 桌面配置文件

const puppeteer = require('puppeteer-core');

(async () => {
  const browser = await puppeteer.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/profiles/win11-desktop-1080p.enc',
    ],
    headless: true,
    defaultViewport: null, // 让配置文件控制视口
  });

  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
})();

使用配置文件自定义窗口大小

# 仅覆盖窗口大小,其他保持配置文件设置
chrome --bot-profile="/profiles/win11-chrome-130.enc" \
       --bot-config-window=1440x900 \
       --bot-config-screen=1920x1080

验证

通过检查完整范围的设备信号来验证设备仿真:

const page = await context.newPage();
await page.goto('https://example.com');

const deviceCheck = await page.evaluate(() => ({
  // 屏幕
  screen: {
    width: screen.width,
    height: screen.height,
    availWidth: screen.availWidth,
    availHeight: screen.availHeight,
  },
  // 窗口
  window: {
    innerWidth: window.innerWidth,
    innerHeight: window.innerHeight,
    outerWidth: window.outerWidth,
    outerHeight: window.outerHeight,
    dpr: window.devicePixelRatio,
  },
  // 触摸
  touch: {
    maxTouchPoints: navigator.maxTouchPoints,
    ontouchstart: 'ontouchstart' in window,
    pointerCoarse: matchMedia('(pointer: coarse)').matches,
    hoverNone: matchMedia('(hover: none)').matches,
  },
  // 硬件
  hardware: {
    deviceMemory: navigator.deviceMemory,
    hardwareConcurrency: navigator.hardwareConcurrency,
  },
}));

console.log('Device verification:', JSON.stringify(deviceCheck, null, 2));
Device Profile Signal Categories Display screen.width/height devicePixelRatio inner/outerWidth colorDepth Input maxTouchPoints pointer: coarse/fine hover: none/hover ontouchstart Hardware deviceMemory hardwareConcurrency WebGL GPU connection type BotBrowser Profile: All signals from one device Internal consistency guaranteed Every signal comes from the same source device capture. No manual configuration. No signal conflicts.

最佳实践

  • 始终使用 defaultViewport: null(Playwright 和 Puppeteer 中)。这让配置文件控制视口尺寸。框架的视口设置会覆盖配置文件值,破坏一致性。
  • 选择匹配你用例的设备配置文件。 对于一般 Web 自动化,使用常见的设备型号。对于移动测试,使用流行手机型号的配置文件。
  • 不要将手动覆盖与配置文件混合使用。 让配置文件控制完整的设备身份。手动覆盖(如在移动配置文件上设置自定义视口)有可能造成信号不一致。
  • 一起验证所有信号类别。 同时检查屏幕、触摸、硬件和 GPU 信号,而非单独检查。
  • 使用 --bot-config-window--bot-config-screen 进行受控覆盖。 当你需要特定尺寸时,这些标志调整显示属性,同时保持所有其他信号一致。
  • 将设备与用例匹配。 对于电商测试,使用消费者手机配置文件。对于企业测试,使用具有典型办公显示器分辨率的桌面配置文件。

常见问题

BotBrowser 是否生成真实的触摸事件?

BotBrowser 在引擎级别启用触摸支持,意味着 maxTouchPointsontouchstart 和 CSS 媒体查询都正确报告。要生成触摸事件序列(点击、滑动、捏合),请使用你的自动化框架的触摸输入 API。Playwright 提供 page.touchscreen.tap(),Puppeteer 提供类似方法。

如果我在移动配置文件中通过 Playwright 设置视口会怎样?

通过 Playwright 或 Puppeteer 设置视口会覆盖配置文件的窗口尺寸。这可能在 innerWidth/innerHeight(由框架设置)和 screen.width/screen.height(由配置文件设置)之间造成不一致。使用 defaultViewport: null 避免这个问题。

我可以自定义屏幕尺寸但保持其他设备信号吗?

可以。使用 --bot-config-window--bot-config-screen 覆盖显示尺寸,同时保持来自配置文件的触摸、内存、GPU 和其他信号。

devicePixelRatio 如何影响截图?

截图时,图像的实际像素尺寸是 width * devicePixelRatio 乘以 height * devicePixelRatio。一个 412px 宽的移动视口配 DPR 2.625 产生 1081 像素宽的截图。

平板配置文件有触摸支持吗?

有。平板配置文件包含触摸支持(通常 maxTouchPoints: 10),配合平板适当的屏幕尺寸和 DPR 值。

我可以在同一浏览器中为不同上下文使用不同的设备配置文件吗?

设备特征通过配置文件在浏览器实例级别设置。同一浏览器内的不同上下文共享相同的设备信号。对于不同的设备身份,需要使用不同配置文件启动独立的浏览器实例。

移动配置文件报告什么 GPU 字符串?

移动配置文件报告来自源设备的 GPU。常见示例包括基于 Qualcomm 设备的 "Adreno (TM) 730",三星 Exynos 设备的 "Mali-G710",以及 iPhone 的 "Apple GPU"。

总结

BotBrowser 中的设备仿真通过从真实硬件采集的配置文件提供完整、一致的设备身份。所有设备信号,从屏幕尺寸和触摸能力到 GPU 字符串和设备内存,都来自同一源设备,确保内部一致性,无需手动配置。

相关主题请参阅Android 仿真了解移动端特定仿真,屏幕和窗口指纹追踪了解屏幕信号详情,以及跨平台配置文件了解跨操作系统运行配置文件。

#Device#Emulation#Touch#Mobile#Platform

让 BotBrowser 从研究走向生产

先用这些指南理解模型,再进入跨平台验证、隔离上下文和面向规模化的浏览器部署。