ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

利用JavaScript与DOM操作实现Steam游戏库批量清理

利用JavaScript与DOM操作实现Steam游戏库批量清理 1. 项目缘起当“喜加一”变成数字垃圾作为一名Steam老玩家我敢说在座的各位谁的库里没躺着几十上百个“喜加一”游戏从Epic每周送到Steam各种限时免费领取再到各种慈善包里的零元购我们总是不由自主地点下那个“添加到账户”的按钮。那一刻的快乐是真实的——不花钱就能拥有一个游戏哪怕它可能是个像素风、评价褒贬不一、甚至你听都没听过的独立小品。但时间一长问题就来了。你的Steam游戏库会变得臃肿不堪。当你真正想找一款游戏来玩时视线会被大量你永远不会打开的免费游戏淹没。更关键的是这些游戏会出现在你的“所有游戏”列表、好友的“最近游玩”动态里甚至影响Steam的推荐算法。它们就像数字空间的“杂物”占据了宝贵的视觉和心智带宽。手动清理那简直是噩梦。Steam客户端和网页版都没有提供批量移除游戏的功能。你需要进入每一个游戏的商店页面点击“管理”再选择“从账户中移除”。面对成百上千的免费游戏这个过程的繁琐程度足以让任何人放弃。于是这些“数字垃圾”就永远留在了你的库里。有没有一种高效、一键式的方法来解决这个问题答案是肯定的。通过浏览器开发者工具F12控制台运行一段简单的JavaScript代码我们就能实现批量、自动化地清理这些不再需要的免费游戏。这不仅是技术上的一个小技巧更是对个人数字资产的一次有效“断舍离”。2. 核心原理如何与Steam网页端“对话”在动手写代码之前我们必须理解我们操作的对象——Steam的网页客户端——是如何工作的。我们并非在破解或入侵Steam而是利用其公开的网页接口模拟用户操作实现自动化。2.1 网页的“骨架”DOM与事件现代网页包括Steam的界面是由一种叫做DOM文档对象模型的树状结构构成的。每一个按钮、每一段文字、每一个链接在DOM中都是一个“节点”。当我们点击网页上的“从账户中移除”按钮时背后发生的是浏览器检测到鼠标点击事件找到对应的DOM节点并执行该节点上绑定的JavaScript函数这个函数会向Steam的服务器发送一个请求。我们的JS代码要做的就是直接找到这些代表“移除”按钮的DOM节点然后以编程方式“触发”它们的点击事件绕过手动点击的步骤。这就像是你雇了一个机器人它能够精准地识别页面上的特定按钮并替你按下去。2.2 Steam账户页面的结构分析要实现精准操作我们需要知道按钮在哪里。以Steam网页版“账户明细”页的游戏列表为例访问路径登录Steam后点击右上角用户名 - “账户明细” - 在“商店和消费历史记录”部分找到“查看许可和产品序列号激活”。这个页面列出了你账户中的所有游戏。页面结构在这个列表中每个游戏条目通常包含游戏名称、添加日期等信息。最关键的是对于大多数免费领取的游戏非免费游玩而是永久拥有其条目右侧会有一个“移除”链接或按钮。目标定位通过浏览器的“检查元素”功能右键点击“移除”按钮选择“检查”我们可以发现这个“移除”按钮的HTML代码特征。例如它可能是一个带有特定class如remove_link的a标签或者其链接地址href中包含特定的关键词如RemoveLicense。我们的脚本核心任务就是在页面中找出所有符合“免费游戏”且带有“移除”按钮特征的DOM元素然后循环触发它们的点击事件。注意Steam会不定期更新其网页前端代码包括类名和结构。因此一段代码可能不会永远有效。本文提供的是一种方法和当前基于近期分析有效的选择器你需要具备根据页面实际情况进行调整的能力。2.3 安全边界与风险提示在开始之前必须明确安全边界仅操作网页元素此方法完全在浏览器中运行只与你当前打开的Steam页面交互不涉及账号密码、不调用未公开的API、不进行任何形式的“破解”。模拟用户操作代码所做的每一个“点击”都和你手动点击在Steam服务器看来没有本质区别。无法撤销通过此方法移除的游戏将永久从你的账户库中消失。虽然你可以重新购买或再次领取如果依然免费但原来的激活记录会被清除。请务必谨慎操作建议先对少数几个不重要的游戏进行测试。遵守服务条款大规模自动化操作可能违反Steam的服务条款。虽然个人小批量、低频率的清理通常不会被追究但理论上存在风险。请负责任地使用。3. 实战代码从单次点击到批量清理理解了原理我们就可以着手编写代码了。我们将从最简单的版本开始逐步构建一个健壮、可用的批量清理脚本。3.1 基础版本找到并点击所有“移除”按钮这是最直接的思路。我们假设Steam页面上所有可移除的许可都对应一个具有特定特征的链接。// 基础版本简单粗暴地点击所有‘移除’链接 (function() { // 尝试寻找带有‘remove_link’类的链接这是Steam曾用过的一种常见类名 let removeLinks document.querySelectorAll(a.remove_link); if (removeLinks.length 0) { console.log(未找到标准的“remove_link”链接。尝试其他选择器...); // 尝试寻找链接文本包含“移除”的按钮 removeLinks Array.from(document.querySelectorAll(a)).filter(link link.textContent.includes(移除)); } console.log(找到了 ${removeLinks.length} 个可能的移除链接。); if (removeLinks.length 0) { alert(未找到任何可移除的游戏链接。请确保你正在正确的页面账户许可页面且页面已完全加载。); return; } // 逐一触发点击事件 removeLinks.forEach((link, index) { console.log(正在点击第 ${index 1} 个链接: ${link.textContent}); // 使用 setTimeout 是为了让操作有一点间隔避免请求过于密集 setTimeout(() { link.click(); }, index * 500); // 间隔500毫秒 }); console.log(已开始自动点击流程。请留意页面弹出的确认对话框); })();代码解读与实操要点document.querySelectorAll(a.remove_link)这是核心选择器。它会在整个页面中寻找所有a标签且其class属性包含remove_link的元素。如果Steam更新了前端这个类名可能失效。备选方案如果上述选择器找不到代码会尝试寻找所有链接文本中包含“移除”二字的a标签。这提高了兼容性。setTimeout这是关键技巧。如果不加延迟所有点击请求会在瞬间同时发出这可能导致Steam服务器端限制或页面行为异常。间隔500毫秒0.5秒是一个比较保守且安全的设置模拟了人类操作的速度。如何运行打开浏览器Chrome/Firefox/Edge均可登录你的Steam账户。进入“账户明细”-“查看许可和产品序列号激活”页面。按下F12键打开开发者工具。切换到Console控制台标签页。将上面的代码完整地复制粘贴到控制台底部的输入行符号后面。按下Enter键执行。执行后控制台会输出找到的链接数量并开始自动点击。此时你的浏览器会弹出第一个确认移除的对话框脚本无法自动点击这个对话框的“确定”按钮出于安全考虑浏览器禁止非用户交互的弹窗自动确认。你需要手动点击“确定”。之后脚本会继续点击下一个链接并再次弹出对话框如此循环。基础版本的局限性需要人工干预每个确认对话框对于清理大量游戏来说依然繁琐。3.2 进阶版本自动处理确认对话框要真正实现“一键清理”我们必须解决确认对话框的问题。这需要更深入地与页面交互。// 进阶版本自动处理确认对话框需要配合浏览器设置或用户首次授权 (function() { // 首先我们需要“欺骗”一下浏览器让它允许我们自动处理后续的confirm对话框。 // 注意这通常只需要在页面生命周期内执行一次。 window.confirm function(message) { console.log(拦截到确认对话框: ${message}。自动选择“确定”。); return true; // 返回 true 相当于点击了“确定” }; // 同样先寻找移除链接 let removeLinks document.querySelectorAll(a.remove_link); if (removeLinks.length 0) { removeLinks Array.from(document.querySelectorAll(a)).filter(link link.textContent.trim() 移除); } if (removeLinks.length 0) { alert(未找到移除链接。); return; } console.log(找到了 ${removeLinks.length} 个移除链接开始自动处理...); // 由于我们重写了confirm现在可以连续点击了 let index 0; function clickNext() { if (index removeLinks.length) { console.log(所有链接已处理完毕。); // 可选恢复默认的confirm行为 // delete window.confirm; return; } let link removeLinks[index]; console.log(处理第 ${index 1}/${removeLinks.length} 个: ${link.closest(tr)?.querySelector(.gameListRowItemName)?.textContent || 未知游戏}); // 触发点击 link.click(); index; // 设置一个延迟让服务器和页面有时间响应 setTimeout(clickNext, 800); // 间隔可以稍长确保稳定性 } // 开始执行 clickNext(); })();代码解读与核心技巧window.confirm function(...) { return true; }这是本脚本的“灵魂”。它重写了浏览器内置的confirm函数。当Steam的代码调用confirm(“您确定要从账户中移除这款游戏吗”)时我们的函数会拦截这个调用直接返回true从而自动确认对话框。这是一个关键技巧但请注意其影响范围仅限于当前标签页的当前页面生命周期。更精准的选择器进阶版中我们尝试寻找链接文本精确等于“移除”的按钮textContent.trim() 移除这比“包含”更精确能避免误点其他链接。递归函数clickNext使用递归而非简单的forEach循环是为了更好地控制流程。每次点击后等待800毫秒再处理下一个形成了一个稳定的操作链。游戏名称提取link.closest(tr)?.querySelector(.gameListRowItemName)?.textContent这行代码尝试从当前链接所在的表格行(tr)中找到游戏名称的单元格。这能让我们在控制台看到正在处理哪个游戏便于监控。选择器.gameListRowItemName是Steam页面中游戏名称常见的类名可能需要根据实际情况调整。实操中的坑与解决方案首次运行可能失败有些浏览器特别是新版Chrome出于安全策略对于window.confirm的重写可能在第一次调用时无效或者会触发警告。如果遇到这种情况一个变通的方法是先手动点击第一个“移除”链接并在弹出的确认对话框中勾选“不要再问我”或类似的选项如果Steam提供的话。这样后续的对话框可能就不再弹出或者我们的重写就能生效了。选择器失效如果控制台输出“未找到移除链接”说明页面结构已变。你需要使用开发者工具的“元素检查”Elements功能右键点击一个“移除”按钮查看它最新的HTML结构和类名然后更新代码中的querySelectorAll参数。网络延迟与错误如果服务器响应慢或者某个请求失败可能会导致脚本中断。更健壮的版本应该加入错误处理try...catch和重试机制但为了代码简洁本文的示例未包含。对于重要操作建议分批进行例如每次处理20个游戏。3.3 安全增强与筛选版本只清理免费游戏前面的版本会尝试移除页面上所有带“移除”按钮的许可这可能包括你付费购买的游戏这非常危险。我们必须增加筛选逻辑只针对“免费喜加一”游戏。如何区分通常在许可列表页面免费游戏所在的行会有一些特征比如没有价格信息或者“购买类型”一栏显示为“免费”或“礼包”。我们需要通过DOM分析来找到这个特征。// 安全增强版本尝试只筛选出免费游戏的移除链接 (function() { // 重写confirm函数 window.confirm function(msg) { console.log(自动确认: ${msg}); return true; }; // 首先找到所有包含游戏信息的行。假设每行是一个tr元素且有一个特定的类例如‘gameListRow’需要根据实际情况调整 let gameRows document.querySelectorAll(table.gameListTable tr:not(:first-child)); // 排除表头行 let freeGameRemoveLinks []; gameRows.forEach(row { // 尝试找到“移除”链接 let removeLink row.querySelector(a.remove_link) || Array.from(row.querySelectorAll(a)).find(a a.textContent.trim() 移除); if (!removeLink) return; // 如果没有移除链接跳过这行 // **关键筛选逻辑**判断这行是否为免费游戏 // 方法1查找包含“免费”文本的单元格 let rowText row.textContent.toLowerCase(); if (rowText.includes(免费) || rowText.includes(free)) { freeGameRemoveLinks.push(removeLink); console.log(识别为免费游戏: ${row.querySelector(.gameListRowItemName)?.textContent}); } // 方法2查找购买类型列需要你知道列的位置例如第4个td // let purchaseTypeCell row.children[3]; // 假设第4列是购买类型 // if (purchaseTypeCell purchaseTypeCell.textContent.toLowerCase().includes(free)) { // freeGameRemoveLinks.push(removeLink); // } }); if (freeGameRemoveLinks.length 0) { alert(未筛选到符合条件的免费游戏移除链接。请检查页面结构或筛选逻辑。); return; } console.log(筛选出 ${freeGameRemoveLinks.length} 个免费游戏的移除链接。); // 询问用户是否继续 if (!confirm(即将自动移除 ${freeGameRemoveLinks.length} 款筛选出的免费游戏。此操作不可逆\n\n此确认由脚本生成点击确定后开始自动流程。)) { console.log(用户取消了操作。); return; } // 开始自动处理 let index 0; function processNext() { if (index freeGameRemoveLinks.length) { console.log(所有免费游戏已处理完毕。); return; } let link freeGameRemoveLinks[index]; console.log(正在移除免费游戏 [${index 1}/${freeGameRemoveLinks.length}]...); link.click(); index; setTimeout(processNext, 1000); // 间隔1秒更稳妥 } processNext(); })();这个版本的重大改进先筛选后操作不再是找到所有链接就点而是先遍历每一行游戏数据通过文本内容如包含“免费”或“free”来判断是否为免费游戏。这是防止误删付费游戏的关键二次确认脚本开始前会用confirm这是我们重写前的那个会被我们的函数拦截向用户展示一个汇总提示列出即将移除的游戏数量让用户做最终决定。更保守的间隔将点击间隔增加到1000毫秒1秒进一步降低对服务器造成压力的风险也更模拟真人操作。重要警告即使有这个筛选逻辑也并非100%安全。Steam页面结构复杂多变免费游戏的标识方式也可能不同。最安全的方式是在运行全自动脚本前先手动检查前几个被筛选出来的游戏是否确实是你不想要的免费游戏。你可以修改脚本在console.log中打印出游戏名先运行一次看看输出列表是否正确。4. 高阶应用与边界情况处理掌握了基础脚本后我们可以探讨一些更复杂但实用的场景和问题。4.1 处理分页与动态加载Steam的许可列表如果游戏数量很多可能会分页显示。我们的脚本默认只对当前页面有效。要清理所有页面的游戏需要处理分页。思路脚本首先清理当前页。清理完成后寻找“下一页”按钮可能是一个链接或带有特定类的元素。自动点击“下一页”按钮。等待新页面加载完成使用setTimeout或监听DOM变化。在新页面上重新执行清理逻辑。这涉及到更复杂的页面状态管理和等待机制代码量会大增。一个更简单的替代方案是Steam许可页面有时可以通过修改URL参数来显示所有项目如pall但这并非官方稳定功能。最务实的方法是手动点击“下一页”然后在每一页上分别运行一次我们的批量清理脚本。4.2 制作浏览器书签工具每次都要打开控制台粘贴代码很麻烦。我们可以将代码制作成一个“书签工具”。新建一个浏览器书签。在网址URL一栏填入以下内容javascript:(function(){/* 将上面‘安全增强版本’的整个代码复制到这里并压缩成一行 */})()注意需要将代码中的所有换行符和多余空格去掉压缩成一行。可以使用在线的JS压缩工具。例如一个极简版本的代码可能是javascript:(function(){window.confirmfunction(){return true;}; let linksdocument.querySelectorAll(a.remove_link); let i0; function c(){if(ilinks.length){links[i].click();i;setTimeout(c,800);}} c();})()警告此极简版本没有筛选逻辑会点击所有移除链接非常危险仅作示例。保存书签命名为“Steam清理工具”。以后需要清理时只需打开Steam许可页面点击一下这个书签即可运行脚本。4.3 应对Steam前端变更这是最大的不确定性。Steam的前端工程师某天更新了类名或页面结构我们的脚本就会失效。应对策略保持代码简洁逻辑清晰我们的脚本核心是“找到按钮 - 点击按钮”。只要这个逻辑在只需要更新“找到按钮”的方法。掌握调试技能学会使用开发者工具的“元素检查”Elements和“控制台”Console是必备技能。当脚本不工作时打开检查工具看看“移除”按钮的HTML代码变成了什么样子然后相应地修改querySelectorAll中的选择器。关注社区Reddit的/r/Steam或一些游戏技术论坛有时会有玩家分享最新的脚本或选择器。4.4 道德与替代方案考量最后我们必须从更广阔的视角看待这个问题。对Steam的影响频繁的自动化请求会给Steam服务器带来不必要的负载。虽然个人清理的影响微乎其微但这是需要考虑的。尽量选择在非高峰时段操作并设置较长的操作间隔如2秒以上。真正的需求我们真的需要彻底移除这些游戏吗Steam有一个“隐藏”游戏的功能在游戏库中右键游戏 - “管理” - “隐藏此游戏”。隐藏后游戏不会出现在你的主库和公开资料中但你仍然拥有它。对于绝大多数“可能未来某天会想玩”的免费游戏隐藏是比移除更优的选择。移除是不可逆的而隐藏是可恢复的。第三方工具风险网络上可能存在一些声称能一键清理的第三方软件或浏览器插件。对这些工具要保持高度警惕它们可能会窃取你的Steam账户凭证Cookie、会话令牌。通过浏览器控制台运行自写的JS代码是风险最低的方式因为代码完全在你的控制下运行在你的浏览器沙盒环境中不涉及向第三方发送数据。因此在按下“确定”前不妨再想想我清理的是“数字垃圾”还是“未来的可能性”对于确定永远不想碰的游戏用本文的方法高效清理对于只是暂时不想看到的使用Steam自带的“隐藏”功能或许是更平衡的数字生活管理策略。技术给了我们选择的权力而如何行使这个权力取决于我们对自己数字生活的理解和规划。
返回列表