Chrome 扩展内容脚本 - 使用 JavaScript 抓取 YouTube 视频标题
Chrome Extension Content Script - Grabbing YouTube video titles using JavaScript
我的 Chrome 扩展程序有一个简单的内容脚本,可以获取 YouTube 视频的标题。我的问题是它只工作过一次。我尝试访问 HTMLCollection 的 child 节点,它应该只是一个,但我得到了 null 和 undefined。做类似的事情:
element[0].innerText;
没有给我任何有用的东西,但根据我的理解,如果我使用 getElementsByClassName 并将 innerText 应用于带有 [0] 的第一个元素,它应该可以工作。 html 没有完全加载可能是一个问题,因为有时我会得到 null 但 HTMLCollection 总是有我想访问的 属性 就坐在那里。
还有:
element.length
returns 0.
这是我的脚本通常得到的结果。
里面是我要抢的"innerText"属性
这就是我得到的一次成功。
{
"manifest_version": 2,
"name": "test",
"author": "Muhammad Amer",
"description": "test",
"version": "1.0",
"content_scripts": [
{
"matches": [
"https://www.youtube.com/*"
],
"js": ["jquery-3.3.1.js", "content.js"]
}
],
"permissions": [
"https://www.youtube.com/*",
"tabs",
"activeTab",
"webNavigation"
]
}
var element = document.getElementsByClassName("title style-scope ytd-video-
primary-info-renderer");
console.log(element);
for (var i = 0; i < element.length; i++) {
var songTitle = element[i].innerText;
console.log(songTitle);
}
在下面post的帮助下,我找到了解决办法:
第一个问题是我的代码执行得太早,所以 setTimeout()
函数解决了这个问题。下一期是我在提到它之前不知道会遇到的一期; YouTube 动态加载它的页面,因此内容脚本仅在页面刷新时运行,而实际上这可能永远不会发生。所以 mutationObserver()
按照评论中的建议努力解决了这个问题。一件奇怪的事情是,我必须观察子列表和子树的突变而不是 characterData,即使改变的是字符数据。根据我的阅读,旧节点被删除,然后新节点被插入。
代码如下:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes.length) {
if (mutation.type == 'childList') {
console.log(mutation.target.innerText);
}
}
})
})
function checkNode() {
var targetNode = document.querySelector("h1.title.style-scope.ytd-video-primary-info-renderer");
if (!targetNode) {
window.setTimeout(checkNode, 500);
return;
}
console.log(targetNode.innerText);
var config = {
childList: true,
subtree:true
}
observer.observe(targetNode, config)
}
checkNode();
我的 Chrome 扩展程序有一个简单的内容脚本,可以获取 YouTube 视频的标题。我的问题是它只工作过一次。我尝试访问 HTMLCollection 的 child 节点,它应该只是一个,但我得到了 null 和 undefined。做类似的事情:
element[0].innerText;
没有给我任何有用的东西,但根据我的理解,如果我使用 getElementsByClassName 并将 innerText 应用于带有 [0] 的第一个元素,它应该可以工作。 html 没有完全加载可能是一个问题,因为有时我会得到 null 但 HTMLCollection 总是有我想访问的 属性 就坐在那里。
还有:
element.length
returns 0.
这是我的脚本通常得到的结果。
里面是我要抢的"innerText"属性
这就是我得到的一次成功。
{
"manifest_version": 2,
"name": "test",
"author": "Muhammad Amer",
"description": "test",
"version": "1.0",
"content_scripts": [
{
"matches": [
"https://www.youtube.com/*"
],
"js": ["jquery-3.3.1.js", "content.js"]
}
],
"permissions": [
"https://www.youtube.com/*",
"tabs",
"activeTab",
"webNavigation"
]
}
var element = document.getElementsByClassName("title style-scope ytd-video-
primary-info-renderer");
console.log(element);
for (var i = 0; i < element.length; i++) {
var songTitle = element[i].innerText;
console.log(songTitle);
}
在下面post的帮助下,我找到了解决办法:
第一个问题是我的代码执行得太早,所以 setTimeout()
函数解决了这个问题。下一期是我在提到它之前不知道会遇到的一期; YouTube 动态加载它的页面,因此内容脚本仅在页面刷新时运行,而实际上这可能永远不会发生。所以 mutationObserver()
按照评论中的建议努力解决了这个问题。一件奇怪的事情是,我必须观察子列表和子树的突变而不是 characterData,即使改变的是字符数据。根据我的阅读,旧节点被删除,然后新节点被插入。
代码如下:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes.length) {
if (mutation.type == 'childList') {
console.log(mutation.target.innerText);
}
}
})
})
function checkNode() {
var targetNode = document.querySelector("h1.title.style-scope.ytd-video-primary-info-renderer");
if (!targetNode) {
window.setTimeout(checkNode, 500);
return;
}
console.log(targetNode.innerText);
var config = {
childList: true,
subtree:true
}
observer.observe(targetNode, config)
}
checkNode();