Javascript PhantomJ在观看YouTube视频时不模仿浏览器行为

Javascript PhantomJ在观看YouTube视频时不模仿浏览器行为,javascript,phantomjs,Javascript,Phantomjs,一周前我把这个问题贴到了PhantomJS邮件列表上,但没有得到回复。希望在这里有更好的运气 我一直在尝试使用PhantomJS从YouTube上抓取信息,但一直没有成功 考虑通过iframe元素嵌入网页的YouTube视频。如果将src属性引用的URL直接加载到浏览器中,则会得到视频的完整页面版本,其中视频被封装在嵌入元素中。嵌入元素不存在于初始页面内容中;相反,页面上的一些脚本标记导致计算一些Javascript,最终将嵌入元素添加到DOM中。我希望能够在这个嵌入元素出现时访问它,但在Pha

一周前我把这个问题贴到了PhantomJS邮件列表上,但没有得到回复。希望在这里有更好的运气

我一直在尝试使用PhantomJS从YouTube上抓取信息,但一直没有成功

考虑通过iframe元素嵌入网页的YouTube视频。如果将src属性引用的URL直接加载到浏览器中,则会得到视频的完整页面版本,其中视频被封装在嵌入元素中。嵌入元素不存在于初始页面内容中;相反,页面上的一些脚本标记导致计算一些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”,所以代码看起来很合理。我只是从来没有找到任何“嵌入”标记,即使我在浏览器中加载上面的URL,我也会在页面加载后很快找到一个


有人知道问题出在哪里吗?提前感谢您的帮助。

幻影确实如此,或者。

帕特里克的回答让我走上了正确的道路,但完整的故事如下

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


原始答案链接:

您是否尝试将完整HTML转储到控制台?可能是YouTube的响应与您在浏览器中看到的不同,可能是基于用户代理过滤。这就是为什么我在上面的代码中将用户代理设置为实际浏览器使用的字符串。Hmmm。你也是。很抱歉在移动设备上发布了该评论。尽管如此:你有没有把完整的HTML扔掉看看你得到了什么?我记不起一周前我在实验中是否尝试过这个。但是,如果我发送的是与浏览器相同的用户代理,是否有任何理由期望使用不同的HTML?我已经编写了一些程序,可以实现相当多的自动web访问,我不能马上想到任何我不能让其正常运行的站点,只要适当地设置用户代理即可。好吧,我同意用户代理可能不是它。但是,由于脚本找不到
标记,问题是为什么找不到。完整的HTML可能会回答这个问题。我不希望它支持这两种东西。我所期望的是Youtube的Javascript应该像在我的浏览器中一样在DOM中添加一个标记,这在PhamtomJS中不会有任何进一步的效果,但我可以读取的属性是-但它不会在视频开始播放之前插入嵌入。查一下其他检查员的消息来源,你把我弄丢了。我根本不希望播放视频,只是为了添加一个嵌入标签。为什么不呢?因为它在你点击开始视频之前不会添加嵌入。这不是我看到的。例如,在我访问上面代码中的URL之后,我可以让我的浏览器检查DOM并告诉我它找到了多少嵌入元素,我得到1个。我当时没有以任何方式与页面交互,当然也没有开始播放视频。嗨@Sean,我正试图用PhantomJS捕捉Youtube的截图,但我就是做不到。我没有看到任何错误-页面正在加载,但视频窗口是黑色的。我试着把你的代码片段放在我的脚本中的任何地方,但每次都是黑色的。你能举一个完整的例子说明如何使用它吗?非常感谢;)@埃拉德,我认为这是不可能的。我的代码只是哄骗Youtube,让它认为phantomjs支持视频播放,这样它就会在页面上插入一个or元素,但phantomjs会忽略这个元素,因为它根本不支持视频。当我想拍摄网站的截图时,这行得通吗?当我得到“此设备不支持视频播放”时,谢谢,为我工作!我发现获得动态加载的视频src的唯一方法是使用您的代码