【问题标题】:Monitor window opening, closing, DOMContentLoaded events for all current & future windows+tabs监控所有当前和未来窗口+选项卡的窗口打开、关闭、DOMContentLoaded 事件
【发布时间】:2012-12-27 14:03:51
【问题描述】:

背景:

我被授权“自动化”第三方网站,以便将“服务订单”推送到其中并监控这些请求的进度。

我尝试采用普通的“抓取”方法(使用 Perl 中的 WWW::MechanizeHTML::Query 等),但遇到了很多问题,无法预测网站中的 JavaScript 会在下面做什么各种情况。如果我从运行 3rd 方站点的产品供应商那里获得支持,或者可以获得一些更好的产品业务规则文档,我打算回到这种方法。

为了避免再次猜测 JavaScript 代码并节省大量时间,我最终采取了一种方法,即在专用 VM 上加载 Firefox 中的 3rd 方站点,然后执行“特权”代码(即:nsI *) 在网站上下文中“驱动”和“抓取”网站。

我目前正在使用 nsIWebProgressListener/DOMContentLoaded(当我已经引用 ChromeWindow 时),以及从 setInterval 调用的 nsIWindowMediator window+tab 枚举来查找新的窗口和标签(当我有由于第 3 方 JavaScript 的作用域,无法预测它们会打开,也无法获得对其 DOMWindow 对象的引用)。

问题: 如何自动将“钩子”安装到由 3rd 方站点的 JavaScript 现在(以及将来)打开的每个窗口/选项卡中?在这种情况下,用于整个 Firefox UI 的“窗口观察者”nsI~ 界面将非常有用。

【问题讨论】:

  • 基本上你想用监听器替换轮询(setInterval)?
  • 这是您可以使用浏览器自动化工具(如Selenium)的东西吗?
  • @h0tw1r3 我希望能够注册一个侦听器,以便为每个适当的事件提供回调。
  • @RichardTowers 不幸的是,没有。 Selenium 无法比我更能预测应用程序的业务逻辑。我真的需要在创建每个窗口/选项卡时捕获它。
  • @RichardTowers 我无法预测新窗口何时会打开(请参阅有关业务规则的要点)。但是,一旦我(以某种方式)检测到打开了一个新窗口,我就可以使用document.locationwindow.opener 以及document 的内容来确定它与应用程序中“当前”窗口的关系。

标签: javascript firefox screen-scraping xul


【解决方案1】:

有很多方法可以做到这一点,所以正确的选择取决于你如何处理其他所有事情。

这里只是倾听的几种方式,而不是轮询。

  1. 新的 Chrome 窗口

    function ChromeWindowObserver() {
        this.observe = function(subject, topic, data) {
           // subject is a ChromeWindow
        }
    }
    Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
          .getService(Components.interfaces.nsIWindowWatcher)
          .registerNotification(new ChromeWindowObserver());
    
  2. 新标签

    function tabListener(event) {
        var browser = gBrowser.getBrowserForTab(event.target):
    }
    gBrowser.tabContainer.addEventListener("TabOpen", tabListener, false);
    
  3. Observer Notifications(我的最爱)

    const dumpObserver = {
        observe: function(subject, topic, data) { dump(topic + "\n"); }
    }
    const domObserver = {
        observe: function(subject, topic, data) { dump(subject.location + "\n"); }
    }
    const ObserverService = Components.classes["@mozilla.org/observer-service;1"]
          .getService(Components.interfaces.nsIObserverService);
    
    /* debug log notifications */
    ObserverService.addObserver(dumpObserver, "*", false);
    /* debug log all new content locations */
    ObserverService.addObserver(domObserver, "content-document-global-created", false);
    

旁注,请查看JavaScript code modules。我认为这可能对您在 chrome 窗口之间共享数据时有所帮助。

【讨论】:

  • 好的,所以如果我强制所有新窗口都在选项卡中(browser.link.open_newwindow.restriction = 0),我可以在tabContainer 上使用TabOpen 事件来查看新选项卡,并且然后在他们的contentWindows 上进行load 事件以获取DOMWindows。这看起来合理吗?
  • 我已经在使用 nsiWindowMediator (Window Listener - onOpenWindow) 来查看新的 Chrome 窗口打开,但我必须在每个新的 Chrome 窗口上安装监听器。 ChromeWindowObserver 似乎是一个更简单的方法!
  • 因为我没有写应用程序,我真的不需要做太多的分享(这都是全局并在任何ChromeWindows打开之前声明)-我只需要驱动并跟随交互,注入/提取一些数据。我绝对可以看到代码模块在 XULRunner 应用程序的多窗口界面中是如何有用的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 2022-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多