PhantomJS 在观看 YouTube 视频时不模仿浏览器行为
PhantomJS not mimicking browser behavior when looking at YouTube videos
我一周前将这个问题发布到 PhantomJS 邮件列表,但没有得到任何回复。希望在这里好运...
我一直在尝试使用 PhantomJS 从 YouTube 上抓取信息,但一直无法正常工作。
考虑通过 iframe 元素将 YouTube 视频嵌入到网页中。如果将 src 属性引用的 URL 直接加载到浏览器中,您将获得视频的整页版本,其中视频封装在嵌入元素中。 embed 元素不存在于初始页面内容中;相反,页面上的某些脚本标记会导致对某些 Javascript 求值,最终将嵌入元素添加到 DOM。我希望能够在它出现时访问这个嵌入元素,但是当我在 PhantomJS 中加载页面时它永远不会出现。
这是我使用的代码:
var page = require("webpage").create();
page.settings.userAgent = "Mozilla/5.0 (X11; rv:24.0) Gecko/20130909 Firefox/24.0";
page.open("https://www.youtube.com/embed/dQw4w9WgXcQ", function (status) {
if (status !== "success") {
console.log("Failed to load page");
phantom.exit();
} else {
setTimeout(function () {
var size = page.evaluate(function () {
return document.getElementsByTagName("EMBED").length;
});
console.log(size);
phantom.exit();
}, 15000);
}
});
无论我设置超时多长时间,我都只看到控制台打印“0”。如果我寻找 "DIV" 元素,我得到“3”,如果我寻找 "SCRIPT" 元素,我得到“5”,所以代码似乎是正确的。我从来没有找到任何 "EMBED" 标签,即使我在我的浏览器中加载上面的 URL 我确实在页面加载后很快找到了一个。
有人知道问题出在哪里吗?在此先感谢您的帮助。
phantomjs not support flash, or the html5 video element.
帕特里克的回答让我走上了正轨,但完整的故事如下。
Youtube 的 Javascript 在决定是否创建某种视频元素之前先探测浏览器的功能。在浏览了缩小的代码后,我最终能够通过将 document.createElement
包装在页面的 onInitialized
回调中来欺骗 Youtube,使其认为 PhantomJS 支持 HTML5 视频。
page.onInitialized = function () {
page.evaluate(function () {
var create = document.createElement;
document.createElement = function (tag) {
var elem = create.call(document, tag);
if (tag === "video") {
elem.canPlayType = function () { return "probably" };
}
return elem;
};
});
};
然而,这是一个失误;为了获得我最初想要的
page.onInitialized = function () {
page.evaluate(function () {
window.navigator = {
plugins: { "Shockwave Flash": { description: "Shockwave Flash 11.2 e202" } },
mimeTypes: { "application/x-shockwave-flash": { enabledPlugin: true } }
};
});
};
这样就完成了。
作为选项 - 尝试自己构建 phantomjs video/audio 支持。
原回答link:https://github.com/ariya/phantomjs/issues/10839#issuecomment-331457673
我一周前将这个问题发布到 PhantomJS 邮件列表,但没有得到任何回复。希望在这里好运...
我一直在尝试使用 PhantomJS 从 YouTube 上抓取信息,但一直无法正常工作。
考虑通过 iframe 元素将 YouTube 视频嵌入到网页中。如果将 src 属性引用的 URL 直接加载到浏览器中,您将获得视频的整页版本,其中视频封装在嵌入元素中。 embed 元素不存在于初始页面内容中;相反,页面上的某些脚本标记会导致对某些 Javascript 求值,最终将嵌入元素添加到 DOM。我希望能够在它出现时访问这个嵌入元素,但是当我在 PhantomJS 中加载页面时它永远不会出现。
这是我使用的代码:
var page = require("webpage").create();
page.settings.userAgent = "Mozilla/5.0 (X11; rv:24.0) Gecko/20130909 Firefox/24.0";
page.open("https://www.youtube.com/embed/dQw4w9WgXcQ", function (status) {
if (status !== "success") {
console.log("Failed to load page");
phantom.exit();
} else {
setTimeout(function () {
var size = page.evaluate(function () {
return document.getElementsByTagName("EMBED").length;
});
console.log(size);
phantom.exit();
}, 15000);
}
});
无论我设置超时多长时间,我都只看到控制台打印“0”。如果我寻找 "DIV" 元素,我得到“3”,如果我寻找 "SCRIPT" 元素,我得到“5”,所以代码似乎是正确的。我从来没有找到任何 "EMBED" 标签,即使我在我的浏览器中加载上面的 URL 我确实在页面加载后很快找到了一个。
有人知道问题出在哪里吗?在此先感谢您的帮助。
phantomjs not support flash, or the html5 video element.
帕特里克的回答让我走上了正轨,但完整的故事如下。
Youtube 的 Javascript 在决定是否创建某种视频元素之前先探测浏览器的功能。在浏览了缩小的代码后,我最终能够通过将 document.createElement
包装在页面的 onInitialized
回调中来欺骗 Youtube,使其认为 PhantomJS 支持 HTML5 视频。
page.onInitialized = function () {
page.evaluate(function () {
var create = document.createElement;
document.createElement = function (tag) {
var elem = create.call(document, tag);
if (tag === "video") {
elem.canPlayType = function () { return "probably" };
}
return elem;
};
});
};
然而,这是一个失误;为了获得我最初想要的
page.onInitialized = function () {
page.evaluate(function () {
window.navigator = {
plugins: { "Shockwave Flash": { description: "Shockwave Flash 11.2 e202" } },
mimeTypes: { "application/x-shockwave-flash": { enabledPlugin: true } }
};
});
};
这样就完成了。
作为选项 - 尝试自己构建 phantomjs video/audio 支持。
原回答link:https://github.com/ariya/phantomjs/issues/10839#issuecomment-331457673