Chrome+JS扩展开发:如何获取下一层页面数据并展示在当前页?
在Twitch当前页面显示主播订阅数的实现方案
由于浏览器同源策略限制,普通网页JS无法直接跨域请求其他页面数据,因此推荐以下两种基于Chrome的可行方案:
方案一:Tampermonkey油猴脚本(快速实现)
这是最便捷的方式,无需打包扩展,直接通过用户脚本实现功能。
步骤
- 安装Chrome的Tampermonkey扩展
- 点击Tampermonkey图标,选择「创建新脚本」
- 替换默认代码为以下内容:
// ==UserScript== // @name Twitch 主播订阅数显示 // @namespace http://tampermonkey.net/ // @version 0.1 // @description 在主播卡片旁显示订阅数 // @author 自定义你的名字 // @match https://www.twitch.tv/* // @grant GM_xmlhttpRequest // @grant GM_addStyle // ==/UserScript== (function() { 'use strict'; // 订阅数样式 GM_addStyle(` .stream-sub-count { color: #9146ff; margin-left: 8px; font-size: 14px; } `); // 从主播页面HTML中提取订阅数 function extractSubCount(html) { const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); // 注意:Twitch DOM结构可能变更,需用F12自行验证选择器 const subElement = doc.querySelector('.tw-stat-value.tw-stat-value--highlight'); return subElement ? subElement.textContent.trim() : 'N/A'; } // 处理单张主播卡片 function processStreamCard(card) { const link = card.querySelector('a[data-a-target="preview-card-image-link"]'); if (!link || card.querySelector('.stream-sub-count')) return; // 用GM_xmlhttpRequest跨域请求主播页面 GM_xmlhttpRequest({ method: 'GET', url: link.href, onload: function(response) { const subCount = extractSubCount(response.responseText); const nickNameElement = card.querySelector('.tw-title'); if (nickNameElement) { const subSpan = document.createElement('span'); subSpan.className = 'stream-sub-count'; subSpan.textContent = `订阅数: ${subCount}`; nickNameElement.appendChild(subSpan); } }, onerror: function() { const nickNameElement = card.querySelector('.tw-title'); if (nickNameElement) { const subSpan = document.createElement('span'); subSpan.className = 'stream-sub-count'; subSpan.textContent = `订阅数: 获取失败`; nickNameElement.appendChild(subSpan); } } }); } // 初始化处理所有已加载的卡片 function init() { const streamCards = document.querySelectorAll('.tw-card.tw-card--hoverable.tw-card--clickable'); streamCards.forEach(card => processStreamCard(card)); } // 监听页面动态加载的新卡片 const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { const targetCards = node.matches('.tw-card.tw-card--hoverable.tw-card--clickable') ? [node] : node.querySelectorAll('.tw-card.tw-card--hoverable.tw-card--clickable'); targetCards.forEach(card => processStreamCard(card)); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); init(); })();
注意事项
- Twitch的DOM结构可能随时更新,需定期用浏览器开发者工具(F12)验证订阅数元素的选择器
- 频繁请求可能触发Twitch反爬机制,可自行添加请求延迟逻辑(比如限制并发数)
方案二:Chrome扩展(长期维护更灵活)
适合需要自定义功能或长期维护的场景,基于Chrome Manifest V3实现。
步骤
- 创建一个扩展目录,包含以下文件:
manifest.json(配置文件)
{ "manifest_version": 3, "name": "Twitch订阅数显示", "version": "1.0", "content_scripts": [ { "matches": ["https://www.twitch.tv/*"], "js": ["content.js"], "css": ["styles.css"] } ], "background": { "service_worker": "background.js" }, "permissions": ["https://www.twitch.tv/*"] }
content.js(页面注入脚本)
// 给卡片添加订阅数元素 function addSubCount(card, subCount) { const nickNameEl = card.querySelector('.tw-title'); if (!nickNameEl || card.querySelector('.sub-count')) return; const span = document.createElement('span'); span.className = 'sub-count'; span.textContent = `订阅数: ${subCount}`; nickNameEl.appendChild(span); } // 处理所有可见卡片 function processCards() { const cards = document.querySelectorAll('.tw-card.tw-card--hoverable.tw-card--clickable'); cards.forEach(card => { const link = card.querySelector('a[data-a-target="preview-card-image-link"]'); if (!link) return; chrome.runtime.sendMessage({ action: 'getSubCount', url: link.href }, (res) => { addSubCount(card, res.subCount || '获取失败'); }); }); } // 监听动态加载内容 const observer = new MutationObserver(processCards); observer.observe(document.body, { childList: true, subtree: true }); // 初始化执行 processCards();
background.js(后台服务脚本)
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'getSubCount') { fetch(request.url) .then(res => res.text()) .then(html => { const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const subElement = doc.querySelector('.tw-stat-value.tw-stat-value--highlight'); sendResponse({ subCount: subElement ? subElement.textContent.trim() : 'N/A' }); }) .catch(() => sendResponse({ subCount: '获取失败' })); return true; // 标记异步响应 } });
styles.css(样式文件)
.sub-count { color: #9146ff; margin-left: 8px; font-size: 14px; }
- 打开Chrome扩展管理页面(
chrome://extensions/),开启「开发者模式」,点击「加载已解压的扩展程序」选择你的扩展目录即可生效。
注意事项
- 若使用Manifest V2,需将
background.service_worker改为background.page - 同样需要关注Twitch DOM结构的变更,及时调整选择器
内容的提问来源于stack exchange,提问作者Hleb Shypula
相关产品推荐
相关产品推荐

