使用 casper 进行实时聊天抓取(Youtube)。选择聚合物元素的问题

Live chat scraping (Youtube) with casper. Issue with selecting polymer elements

我正在尝试使用 casper 从 youtube 实时聊天提要中抓取文本。我在 select 正确 selector 时遇到问题。每条被推出的新消息都有许多嵌套元素和动态生成的元素。如何才能不断拉动嵌套的

<span id="message">some message</span>

它们发生的时间?我目前似乎连一个都抓不到!这是我的测试代码: 注意:您可以替换任何具有实时聊天提要的 youtube url。

const casper = require("casper").create({
  viewportSize: {
    width: 1080,
    height: 724
  }
});
const ua = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'
const url = "https://www.youtube.com/watch?v=NksKCLsMUsI";
casper.start();
casper.userAgent(ua)
casper.thenOpen(url, function() {
  this.wait(3000, function() {
    if (this.exists("span#message")) {
      this.echo("found the a message!");
    } else {
      this.echo("can't find a message");
    }
    casper.capture("test.png");
  });
});

casper.run();

我的问题就是这个。我如何正确 select 消息? 2,我怎样才能不断收听新的?

更新:我一直在玩噩梦(电子测试套件),这看起来很有希望,但我似乎仍然无法 select 聊天元素。我知道我错过了一些简单的东西。

编辑/更新(使用 cadabra 的优秀示例)

var casper = require("casper").create({
  viewportSize: {
    width: 1024,
    height: 768
  }
});

url = 'https://www.youtube.com/live_chat?continuation=0ofMyAMkGiBDZzhLRFFvTFJVRTFVVlkwZEV4MFRFVWdBUSUzRCUzRDAB'
ua = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'

casper.start(url)
casper.userAgent(ua);

var currentMessage = '';

(function getPosts() {
  var post = null;

  casper.wait(1000, function () {
    casper.capture('test.png')
    post = this.evaluate(function () {
      var nodes = document.querySelectorAll('yt-live-chat-text-message-renderer'),
          author = nodes[nodes.length - 1].querySelector('#author-name').textContent,
          message = nodes[nodes.length - 1].querySelector('#message').textContent;

      return {
        author: author,
        message: message
      };
    });
  });

  casper.then(function () {
    if (currentMessage !== post.message) {
      currentMessage = post.message;
      this.echo(post.author + ' - ' + post.message);
    }
  });

  casper.then(function () {
    getPosts();
  });
})();

casper.run();

这比你想象的要难得多...看看我尝试了什么,但没有成功:

1。使用 ignore-ssl-errors 选项

YouTube 使用 HTTPS。这对我们来说是一个真正的问题,因为 PhantomJS 不太喜欢 SSL/TLS...这里我们需要使用 ignore-ssl-errors。该选项可以在命令行中传递:

casperjs --ignore-ssl-errors=true script.js

2。访问聊天页面而不是 iframe

我们试图抓取的评论不在主页中。它们来自加载在 iframe 中的外部页面。在 CasperJS 中,我们可以使用 withFrame() 方法,但这对于我们可以直接访问的东西来说是无用的复杂性...

Main page | Chat page

3。使用 PhantomJS (WebKit) 和 SlimerJS (Gecko) 进行测试

由于 YouTube 的限制,两种浏览器给出相同的结果:

Oh no!
It looks like you're using an older version of your browser. Please update it to use live chat.

如果你想测试自己,这里是脚本:

var casper = require("casper").create({
  viewportSize: {
    width: 1080,
    height: 724
  }
});

casper.start('https://www.youtube.com/live_chat?continuation=0ofMyAMkGiBDZzhLRFFvTFRtdHpTME5NYzAxVmMwa2dBUSUzRCUzRDAB');

casper.wait(5000, function () {
  this.capture('chat.png');
});

casper.run();

PhantomJS: casperjs --ignore-ssl-errors=true script.js

SlimerJS: casperjs --engine=slimerjs script.js

结论:您可能需要使用 真正的 网络浏览器,如 Firefox 或 Chromium 才能实现此目的。像 Nightwatch.js 这样的自动化框架可以帮助...


编辑 1

好的,所以...使用您的 user-agent 字符串,这是可行的:

var casper = require("casper").create({
  viewportSize: {
    width: 1080,
    height: 724
  }
});

casper.userAgent('Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0');

casper.start('https://www.youtube.com/live_chat?continuation=0ofMyAMkGiBDZzhLRFFvTFRtdHpTME5NYzAxVmMwa2dBUSUzRCUzRDAB');

casper.wait(5000, function () {
  this.each(this.evaluate(function () {
    var res = [],
        nodes = document.querySelectorAll('yt-live-chat-text-message-renderer'),
        author = null,
        message = null;

    for (var i = 0; i < nodes.length; i++) {
      author = nodes[i].querySelector('#author-name').textContent.toUpperCase();
      message = nodes[i].querySelector('#message').textContent.toLowerCase();
      res.push(author + ' - ' + message);
    }

    return res;
  }), function (self, post) {
    this.echo(post);
  });
});

casper.run();

使用此脚本,您应该会在终端中看到对话中的最新消息。 :)


编辑 2

由于视频回来了,我花了一些时间修改我以前的代码,用递归的 IIFE 实现实时轮询。通过以下脚本,我可以获取聊天流中的最新评论。每秒发送一个请求以刷新内容,并过滤帖子以避免重复。

var casper = require("casper").create({
  viewportSize: {
    width: 1080,
    height: 724
  }
});

casper.userAgent('Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0');

casper.start('https://www.youtube.com/live_chat?continuation=0ofMyAMkGiBDZzhLRFFvTFRtdHpTME5NYzAxVmMwa2dBUSUzRCUzRDAB');

var currentMessage = '';

(function getPosts() {
  var post = null;

  casper.wait(1000, function () {
    post = this.evaluate(function () {
      var nodes = document.querySelectorAll('yt-live-chat-text-message-renderer'),
          author = nodes[nodes.length - 1].querySelector('#author-name').textContent,
          message = nodes[nodes.length - 1].querySelector('#message').textContent;

      return {
        author: author,
        message: message
      };
    });
  });

  casper.then(function () {
    if (currentMessage !== post.message) {
      currentMessage = post.message;
      this.echo(post.author + ' - ' + post.message);
    }
  });

  casper.then(function () {
    getPosts();
  });
})();

casper.run();

它在我的电脑上完美