身份

浏览历史注入:生成真实历史记录

如何向浏览器配置文件注入真实的浏览历史,支持自定义历史深度控制,以匹配真实用户行为的自然使用模式。

文档中心

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

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

简介

每个真实的浏览器都会随着时间积累浏览历史。后退按钮有地方可去,history.length 大于一,浏览器的内部历史存储包含跨越数天或数周的条目。刚启动的零历史浏览器与具有自然使用痕迹的浏览器截然不同。对于隐私研究、测试和多账户管理,浏览历史的状态是整体浏览器身份的重要组成部分。

BotBrowser 提供 --bot-inject-random-history 标志(PRO 层级),在启动时向浏览器会话填充合成浏览历史。生成的历史包括来自热门网站的条目,具有不同的时间戳,在任何自动化开始之前创建真实的使用痕迹。此标志与 --bot-cookies--bot-bookmarks 等其他身份信号配合工作,创建从一开始就看起来自然使用过的浏览器会话。

隐私影响:为什么浏览历史很重要

history.length 属性可被页面上运行的任何 JavaScript 访问。全新的浏览器会话始终以 history.length 为 1(当前页面)开始。具有先前导航历史的浏览器具有更高的值。这个简单的数字揭示了浏览器在当前会话中是否曾被使用过。

除了 history.length 之外,零历史浏览器的整体行为与具有累积状态的浏览器不同。导航模式、前进/后退按钮的可用性和会话恢复行为都取决于历史状态。研究浏览器指纹的隐私研究人员需要控制此信号以创建一致的、可重复的测试环境。

对于多账户管理,每个身份应该看起来有独立的浏览历史,反映自然使用。总是以干净历史开始的浏览器看起来像全新安装,这不是大多数用户与浏览器交互的方式。添加合成历史创建了一个更完整的身份,与配置文件提供的其他信号一致。

技术背景

浏览历史在 Chromium 中如何工作

Chromium 在用户数据目录中的 SQLite 数据库中维护浏览历史。该数据库存储:

  • 访问的 URL:每个访问页面的完整 URL
  • 访问时间戳:每个页面被访问的时间,精确到微秒
  • 访问次数:每个 URL 被访问的次数
  • 转换类型:用户如何到达该页面(输入、链接点击、重定向等)
  • 引荐来源:哪个页面导致了该访问

JavaScript 中的 history.length 属性反映当前标签的会话历史(前进/后退栈)中的条目数量,而不是总浏览历史。然而,整体历史数据库状态影响地址栏(omnibox)建议、新标签页上的"最常访问"磁贴和 chrome://history 的历史搜索界面等功能。

会话历史与全局历史

两种类型的历史之间有重要区别:

会话历史是每个标签的,追踪单个标签内的前进/后退导航。这是 history.lengthhistory.back()history.forward() 交互的内容。标签关闭时重置。

全局历史是跨所有标签和会话的浏览器范围的所有访问 URL 记录。存储在历史数据库中,跨浏览器重启持久化(除非用户清除它)。

BotBrowser 的 --bot-inject-random-history 标志填充全局历史数据库,使浏览器拥有出现在 chrome://history 中并影响地址栏建议的真实历史痕迹。

常见方法及其局限性

脚本导航

创建浏览历史最直接的方式是在开始实际任务之前实际访问网站。这意味着导航到一系列 URL,等待每个加载完成,然后继续自动化。此方法可行但有显著缺点:

  1. 时间成本:加载 20-50 个页面需要数十秒到几分钟,取决于页面复杂性和网络速度
  2. 网络开销:每次页面加载产生真实的网络流量,消耗代理带宽,可能触发速率限制
  3. 副作用:真实页面加载执行 JavaScript、设置 cookie、触发分析事件,可能在实际任务开始前触发追踪系统
  4. 不确定性:页面加载时间、重定向和动态内容使历史生成过程不可预测

用户数据目录重用

重用已包含前一会话历史的 --user-data-dir 会自动保留浏览历史。然而,这也保留了所有其他状态(缓存、cookie、本地存储、service worker),无法精细控制保留哪些信号和重置哪些信号。

JavaScript history.pushState

history.pushState() API 可以在不导航的情况下向会话历史添加条目,但它只在同一来源内工作,且只影响当前标签的会话历史。它不向全局浏览历史数据库添加条目或影响地址栏建议。

BotBrowser 的方案

BotBrowser 的 --bot-inject-random-history 标志在启动时生成合成浏览历史,在任何页面加载之前。这种方法避免了脚本导航的性能和副作用问题,同时产生真实的历史状态。

三种操作模式

该标志支持三种模式(2026 年 3 月更新):

  • --bot-inject-random-history--bot-inject-random-history=true:注入随机数量的历史条目(2-7 条)。这是默认行为。
  • --bot-inject-random-history=15:精确注入 15 条历史记录。生成的 history.length 将为 16(15 条注入记录 + 当前页面)。可以指定任意正整数。
  • --bot-inject-random-history=false:完全禁用历史注入。

={number} 语法让你可以精确控制历史深度,当需要在多个会话之间保持一致的 history.length 值时非常有用。

生成的内容

该标志产生的历史条目包括:

  • 热门网站:来自典型用户会访问的知名域名的条目
  • 不同的时间戳:访问分散在真实的时间范围内,不集中在某一时刻
  • 多样的域名:生成的历史涵盖多个类别(搜索、新闻、社交、购物)以反映自然的浏览模式
  • 真实的访问次数:某些 URL 出现多次,模仿频繁访问网站的模式

引擎级别的填充

历史条目在初始化期间插入浏览器的历史数据库。这意味着它们在任何浏览器上下文创建和任何页面加载之前可用。地址栏、chrome://history 和新标签页都立即反映填充的历史。

无网络开销

因为历史是合成生成的而非通过实际页面访问,所以没有网络流量、没有页面加载、没有 JavaScript 执行。与脚本导航相比,历史填充增加的启动时间可以忽略不计。

适用于全新用户数据目录

该标志适用于新的 --user-data-dir 目录。你不需要提前准备或填充目录。每次使用全新临时目录和 --bot-inject-random-history 启动都会产生一组新的历史条目。

配置与使用

基本 CLI 使用

# 随机历史(2-7 条记录)
chrome --bot-profile="/path/to/profile.enc" \
       --bot-inject-random-history \
       --user-data-dir="$(mktemp -d)"

# 精确数量:注入 15 条记录(history.length = 16)
chrome --bot-profile="/path/to/profile.enc" \
       --bot-inject-random-history=15 \
       --user-data-dir="$(mktemp -d)"

Puppeteer 集成

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

(async () => {
  const browser = await puppeteer.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
      // 使用 =N 指定精确数量,或省略值使用随机模式(2-7)
      '--bot-inject-random-history=10',
    ],
    headless: true,
    defaultViewport: null,
  });

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

  const historyLength = await page.evaluate(() => history.length);
  console.log('History length:', historyLength); // 11(10 + 当前页面)
  await browser.close();
})();

Playwright 集成

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

(async () => {
  const browser = await chromium.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
      // 使用 =N 指定精确数量,或省略值使用随机模式(2-7)
      '--bot-inject-random-history=20',
    ],
    headless: true,
  });

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

完整身份设置

将历史与书签、cookie 和区域设置结合以获得完整的身份:

chrome --bot-profile="/path/to/profile.enc" \
       --bot-inject-random-history \
       --bot-bookmarks='[{"title":"Google","type":"url","url":"https://www.google.com"},{"title":"YouTube","type":"url","url":"https://www.youtube.com"}]' \
       --bot-cookies="@/path/to/cookies.json" \
       --bot-always-active \
       --bot-config-timezone=Europe/London \
       --bot-config-locale=en-GB \
       --bot-config-languages=en-GB,en

验证

使用 --bot-inject-random-history 启动后,验证历史是否已填充:

const page = await browser.newPage();

// Check session history length (should be > 1 after some navigation)
await page.goto('https://example.com');
const historyLength = await page.evaluate(() => history.length);
console.log('Session history length:', historyLength);

// Navigate to the history page to see global history
await page.goto('chrome://history');
// The history page should show entries from the synthetic history
History Population: Synthetic vs. Scripted --bot-inject-random-history No network traffic Instant population No JS side effects Works with fresh data dir Scripted Navigation Real HTTP requests Seconds to minutes Triggers analytics/tracking Non-deterministic timing

最佳实践

  • 每个会话使用全新的 user-data-dir。 每个会话应该用自己的数据目录开始,避免携带非预期的状态:--user-data-dir="$(mktemp -d)"
  • 与 --bot-always-active 结合使用。 --bot-always-active 标志(PRO 层级,默认启用)保持窗口处于活动状态,使会话看起来更像活跃的浏览。
  • 历史与身份匹配。 当历史与区域设置和时区标志一起使用时,组合创建一个连贯的身份。
  • 与 --bot-bookmarks 结合使用。 书签和历史共同创建比单独使用更完整的浏览器身份。
  • 不要仅依赖 history.length 进行验证。 会话历史和全局历史是不同的。检查 chrome://history 以获得完整视图。

常见问题

生成的历史中出现哪些网站?

生成的历史包括跨多个类别的热门知名网站的条目。具体条目是多样化的,以创建真实的浏览模式。

生成的历史是否匹配配置文件的区域设置?

历史生成产生一组通用的热门全球网站。对于区域特定的历史,生成的条目由你通过其他标志提供的区域设置和时区设置补充。

我可以控制历史中出现哪些 URL 吗?

--bot-inject-random-history 标志自动生成历史。对于自定义 URL 列表,你需要使用脚本导航或用户数据目录管理。

这是否影响 JavaScript 中的 history.length?

该标志填充全局浏览历史(chrome://history 数据库)。JavaScript 中的 history.length 属性反映当前标签的会话历史,新标签从 1 开始。导航到页面后,history.length 正常递增。

--bot-inject-random-history 需要什么层级?

--bot-inject-random-history 标志在 PRO 层级可用。

可以在 Docker 或无头服务器部署中使用吗?

可以。该标志在所有部署环境中工作,包括 Docker 容器和无头 Linux 服务器。历史生成不需要显示器或 GUI。

这如何与 --user-data-dir 交互?

如果你提供全新的临时目录,历史从零生成。如果你重用现有目录,合成历史会添加到该目录中的任何现有历史旁边。

如何控制精确的 history.length 值?

使用 ={number} 语法。例如,--bot-inject-random-history=15 精确注入 15 条历史记录,因此导航到页面后 history.length 将为 16(15 条注入 + 1 个当前页面)。当你需要在多个会话之间保持特定的、可重现的历史深度时,这非常有用。不使用 ={number} 后缀时,该标志注入 2 到 7 之间的随机数量。

总结

--bot-inject-random-history 标志为 BotBrowser 会话添加真实的浏览历史,无需脚本导航的开销和副作用。结合书签、cookie 和区域设置配置,它创建具有完整使用痕迹的浏览器身份。

有关相关主题,请参阅 Cookie 管理 了解会话持久化,书签预填充 了解书签设置,以及 配置文件管理 了解身份集的组织。

#History#Injection#Identity#Browsing#Privacy

让 BotBrowser 从研究走向生产

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