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;
    };
  });
};

然而,这是一个失误;为了获得我最初想要的 标签,我需要让 Youtube 的代码认为 PhantomJS 支持 Flash,而不是 HTML5 视频。这也是可行的:

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