迁移 Arc Browser 自定义搜索引擎列表
Generated by gpt-5.5
介绍
最近打算弃用 Arc Browser 回归 Google Chrome 了,但是 Arc 保存了很多自定义搜索引擎,发现没有合适的导出工具,遂撰写这篇文章。
Arc Browser 和 Google Chrome 都是 Chromium 系浏览器,自定义搜索引擎保存在 profile 目录下的 Web Data SQLite 数据库中。核心表是 keywords。
数据库路径
- Arc 默认 profile:
~/Library/Application Support/Arc/User Data/Default/Web Data - Chrome 默认 profile:
~/Library/Application Support/Google/Chrome/Default/Web Data
迁移前先退出 Chrome。否则数据库可能处于 locked 状态。
TL;DR
可以使用如下命令一键迁移:
uvx chromium-search-migrator \
"$HOME/Library/Application Support/Arc/User Data/Default/Web Data" \
"$HOME/Library/Application Support/Google/Chrome/Default/Web Data" \
--apply
备份
备份数据库
退出 Chrome,然后备份 Chrome 数据库:
cp "$HOME/Library/Application Support/Google/Chrome/Default/Web Data" \
"/tmp/chrome-default-web-data.bak"
检查备份是否正常:
sqlite3 "/tmp/chrome-default-web-data.bak" "PRAGMA integrity_check;"
输出 ok 即可。
检查表结构
Arc 和 Chrome 的 keywords 表结构需要一致:
sqlite3 "$HOME/Library/Application Support/Arc/User Data/Default/Web Data" \
"PRAGMA table_info(keywords);"
sqlite3 "$HOME/Library/Application Support/Google/Chrome/Default/Web Data" \
"PRAGMA table_info(keywords);"
字段包括:short_name、keyword、favicon_url、url、suggest_url、sync_guid、is_active、url_hash 等。
导入
dry-run
下面的查询会统计 Arc 中 active,并且在 Chrome 中没有同名 keyword、也没有相同 url 的 search engine:
sqlite3 "$HOME/Library/Application Support/Google/Chrome/Default/Web Data" \
"ATTACH '$HOME/Library/Application Support/Arc/User Data/Default/Web Data' AS arc;
SELECT COUNT(*)
FROM arc.keywords a
WHERE a.is_active = 1
AND NOT EXISTS (SELECT 1 FROM main.keywords c WHERE c.keyword = a.keyword)
AND NOT EXISTS (SELECT 1 FROM main.keywords c WHERE c.url = a.url);"
导入数据
使用事务导入,并跳过已存在的 keyword 和 url:
sqlite3 "$HOME/Library/Application Support/Google/Chrome/Default/Web Data" \
"ATTACH '$HOME/Library/Application Support/Arc/User Data/Default/Web Data' AS arc;
BEGIN IMMEDIATE;
INSERT INTO main.keywords (
short_name,
keyword,
favicon_url,
url,
safe_for_autoreplace,
originating_url,
date_created,
usage_count,
input_encodings,
suggest_url,
prepopulate_id,
created_by_policy,
last_modified,
sync_guid,
alternate_urls,
image_url,
search_url_post_params,
suggest_url_post_params,
image_url_post_params,
new_tab_url,
last_visited,
created_from_play_api,
is_active,
starter_pack_id,
enforced_by_policy,
featured_by_policy,
url_hash
)
SELECT
a.short_name,
a.keyword,
a.favicon_url,
a.url,
a.safe_for_autoreplace,
a.originating_url,
a.date_created,
a.usage_count,
a.input_encodings,
a.suggest_url,
a.prepopulate_id,
a.created_by_policy,
a.last_modified,
lower(hex(randomblob(16))),
a.alternate_urls,
a.image_url,
a.search_url_post_params,
a.suggest_url_post_params,
a.image_url_post_params,
a.new_tab_url,
a.last_visited,
a.created_from_play_api,
1,
a.starter_pack_id,
a.enforced_by_policy,
a.featured_by_policy,
a.url_hash
FROM arc.keywords a
WHERE a.is_active = 1
AND NOT EXISTS (SELECT 1 FROM main.keywords c WHERE c.keyword = a.keyword)
AND NOT EXISTS (SELECT 1 FROM main.keywords c WHERE c.url = a.url);
COMMIT;"
为了避免直接复用 Arc 数据库里的同步 ID,这里重新生成了 sync_guid:
lower(hex(randomblob(16)))
验证
查看导入后的总数:
sqlite3 "$HOME/Library/Application Support/Google/Chrome/Default/Web Data" \
"SELECT COUNT(*) FROM keywords;
SELECT COUNT(*) FROM keywords WHERE is_active = 1;
SELECT COUNT(*) FROM keywords WHERE is_active = 0;"
检查数据库完整性:
sqlite3 "$HOME/Library/Application Support/Google/Chrome/Default/Web Data" \
"PRAGMA integrity_check;"
查看前几条 active search engine:
sqlite3 -header -column "$HOME/Library/Application Support/Google/Chrome/Default/Web Data" \
"SELECT short_name, keyword, url
FROM keywords
WHERE is_active = 1
ORDER BY short_name COLLATE NOCASE, keyword COLLATE NOCASE
LIMIT 20;"
然后打开 Chrome,进入:
chrome://settings/searchEngines
确认搜索引擎是否已经出现。
恢复
如果 Chrome 启动后发现异常,退出 Chrome,然后恢复备份:
cp "/tmp/chrome-default-web-data.bak" \
"$HOME/Library/Application Support/Google/Chrome/Default/Web Data"
备注
%s 在 Chromium 数据库中通常保存为 {searchTerms}。例如:
https://man.archlinux.org/search?q=%s&go=Go
在 keywords.url 中会变成:
https://man.archlinux.org/search?q={searchTerms}&go=Go

浙公网安备 33010602011771号