使用zombie.js进行网站抓取的问题

Nik*_* B. 9 javascript facebook screen-scraping node.js zombie.js

我需要做一些网络抓取.在玩了不同的Web测试框架之后,其中大部分都是太慢(Selenium)或者太多我的需求(env.js),我认为zombie.js看起来最有希望,因为它使用了一组可靠的库HTML解析和DOM操作.但是,在我看来,它甚至不支持基本的基于事件的Javascript代码,如下面的网页:

<html>
  <head>
    <title>test</title>
    <script type="text/javascript">

      console.log("test script executing...");
      console.log("registering callback for event DOMContentLoaded on " + document);

      document.addEventListener('DOMContentLoaded', function(){
        console.log("DOMContentLoaded triggered");
      }, false);

      function loaded() {
        console.log("onload triggered");
      }

    </script>
  </head>

  <body onload="loaded();">
    <h1>Test</h1>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

然后我决定手动触发这些事件,如下所示:

zombie = require("zombie");

zombie.visit("http://localhost:4567/", { debug: true }, function (err, browser, status) {

  doc = browser.document;
  console.log("firing DOMContentLoaded on " + doc);
  browser.fire("DOMContentLoaded", doc, function (err, browser, status) {

    body = browser.querySelector("body");
    console.log("firing load on " + body);
    browser.fire("load", body, function (err, browser, status) {

      console.log(browser.html());

    });
  });

});
Run Code Online (Sandbox Code Playgroud)

哪个适用于此特定测试页面.我的问题是一个更普遍的问题:我希望能够在Facebook上搜索更复杂,基于AJAX的网站,例如朋友列表(类似于http://www.facebook.com/profile.php?id=100000028174850&sk =朋友和朋友=朋友).使用zombie登录网站没有问题,但是像这些列表这样的内容似乎是使用AJAX动态完全加载的,我不知道如何触发启动加载的事件处理程序.

关于这个问题我有几个问题:

  • 有人在没有使用像Selenium这样的浏览器远程控制解决方案的情况下已经实现了类似的复杂刮刀吗?
  • 是否有一些关于基于Javascript的复杂页面的加载过程的参考?
  • 有人可以提供有关如何调试真实浏览器的建议,以查看我可能需要执行什么来触发Facebook事件处理程序吗?
  • 有关此主题的任何其他想法?

再一次,请不要指出涉及控制像Selenium这样的真实浏览器的解决方案,正如我所知道的那样.然而,对于可以从Ruby脚本语言访问的真实内存渲染器(如WebKit)的建议是值得欢迎的,但最好能够设置cookie,并且最好还加载原始HTML而不是触发真正的HTTP请求.

jch*_*hes 13

出于数据提取的目的,运行"无头浏览器"并手动触发javascript事件并不是最容易的事情.虽然并非不可能,但有更简单的方法可以做到这一点.

大多数网站,甚至是AJAX重的网站,都可以在不执行单行Javascript代码的情况下进行删除.实际上,它通常比试图找出网站的Javascript代码更容易,这些代码经常被混淆,缩小,并且难以调试.如果您对HTTP有充分的了解,您将理解为什么:(几乎)与服务器的所有交互都被编码为HTTP请求,因此无论它们是由Javascript启动,还是用户单击链接,或者是机器人程序中的自定义代码,这与服务器没有区别.(我说几乎是因为当Flash或小程序介入时,无法确定哪些数据在哪里飞行;它们可能是特定于应用程序的.但是在Javascript中完成的任何操作都将通过HTTP进行.)

话虽这么说,可以使用自定义软件模仿任何网站上的用户.首先,您必须能够看到发送到服务器的原始HTTP请求.您可以使用代理服务器将真实浏览器发出的请求记录到目标网站.你可以使用很多很多工具:CharlesFiddler很方便,大多数专用的屏幕刮刀工具都内置了基本的代理,Firefox和Chrome 的Firebug扩展有类似的工具来查看AJAX请求...你明白了.

一旦您可以看到由于网站上的特定操作而产生的HTTP请求,就可以轻松编写程序来模仿这些请求; 只需将相同的请求发送到服务器,它就会像执行特定操作的浏览器一样处理您的程序.

对于提供不同功能的不同语言,存在不同的库.对于红宝石,我看到很多人使用机械化红宝石.

如果数据提取是您唯一的目标,那么您几乎总能通过这种方式模仿HTTP请求来获得所需内容.不需要Javascript.

注意 - 自从你提到Facebook之后,我应该提到特别难以抓取Facebook(虽然并非不可能),因为Facebook已经采取措施来检测自动访问(他们使用的不只是验证码); 如果他们看到来自该帐户的可疑活动,他们将停用该帐户.毕竟,这违反了他们的服务条款(第3.2节).

  • 网站现在检查HTTP请求的顺序和时间是(统计上)正确的. (2认同)