XULRunner with Java: JavaXPCOM Tutorial 4

本文介绍如何使用JavaXPCOM实现自动浏览网页,包括加载网页、等待加载完成及通过XPath抽取页面元素。

7. 用JavaXPCOM来自动浏览网页
   在这一节里我们将解决一些自动浏览网页中的一些问题,尝试把一下通用的任务抽象成人类可读的方法,因此你可以轻易的阅读

代码并知道它的功能。我们将构建一个Web Browser来加载网页,点击按钮或者超链接,使用XPath来抽取一下有用的信息。在每一个

小节里面,我们都将在我们的浏览器里增加新的功能,因此在最后,我们将有一个Web Browser,它能够实现网页的自动
浏览。

7.1 使用我们的浏览器来加载网页
    在例子 SimpleBrowser里,我们使用方法 public boolean setUrl(String url) 来让浏览器加载一个url。这个方法的问题是它

可以让浏览器开始加载一个页面,但是不会等待浏览器加载页面完成。我们写了一个方法叫做go来实现这个功能,因此后面我们将使

用这种方法来安全的加载一个页面,阻塞住执行流程直到页面加载成功或者超时。
    注:实现的方法是在setUrl的时候定义一个CountDownLatch,然后监听browser.addProgressListener,等页面完成后把这个

CountDownLatch countDown一下。调用setUrl后使用CountDownLatch的await方法等待加载完成或者超时。注意调用setUrl时要启动

一个SWT线程       
               display.syncExec(new Runnable() {
            public void run() {
                browser.setUrl(url);
            }
        });
    另外,我们可能还想获得加载后的页面内容,所有译者增加了一个变量content。增加的代码如下
                browser.addProgressListener(new ProgressListener() {
                    public void changed(ProgressEvent event) {
                    }

                    public void completed(ProgressEvent event) {
                        // When a page is loaded, decrement the latch,
                        // which count will be 0 after this call.
                        latch.countDown();
                        content=browser.getText();// added by LiLi
                    }
                });



7.2 解析XPath来获得W3C Node
    一旦我们能够在浏览器里加载一个HTML页面,我们可能想访问DOM节点来抽取信息。前面我们花了一节来吧Mozilla Node转换成

W3C node。现在我们使用那个方法来用标准的方法操作W3C Node。我们实现了一些方法来创建XPath Evaluator和XPath resolver来

抽取节点。当Xpath evaluator返回一个结果,我们把每个返回的DOM node转换成响应的W3C DOM element,使用的方法是 static

Node getNodeInstance( nsIDOMNode node ) 。因此,使用我们的browser可以直接调用下面的方法:

 

下面是完整的例子:

译注:核心代码就是下面这个方法。它有两个参数,xpath和nsIDOMNode,返回的是满足XPath的Node的list。
Node是W3C Node 。其实就是调用xpcom的接口来做xpath解析,然后把nsIDOMNode的List转成W3C Node的list。
不过我感觉其实没有必要,nsIDOMNode的属性更多,而且W3C Node没办法转回去成为nsIDOMNode。在使用XPath的时候,我们可能先

用绝对XPath找到某个table,然后根据相对XPath找tr,td等。第二次调用xPathNodes是的参数 nsIDOMNode context就是第一次返回

的结果里的nsIDOMNode。

 

!SESSION 2025-05-26 20:01:51.887 ----------------------------------------------- eclipse.buildId=4.29.0.20230907-1200 java.version=17.0.8.1 java.vendor=Eclipse Adoptium BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=zh_CN Framework arguments: -product org.eclipse.epp.package.java.product Command-line arguments: -os linux -ws gtk -arch x86_64 -product org.eclipse.epp.package.java.product !ENTRY ch.qos.logback.classic 1 0 2025-05-26 20:02:04.760 !MESSAGE Activated before the state location was initialized. Retry after the state location is initialized. !ENTRY org.eclipse.osgi 4 0 2025-05-26 20:02:07.219 !MESSAGE Application error !STACK 1 java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons: no swt-pi4-gtk-4962r3 in java.library.path: /usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib no swt-pi4-gtk in java.library.path: /usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib no swt-pi4 in java.library.path: /usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib Can't load library: /root/.swt/lib/linux/x86_64/libswt-pi4-gtk-4962r3.so Can't load library: /root/.swt/lib/linux/x86_64/libswt-pi4-gtk.so Can't load library: /root/.swt/lib/linux/x86_64/libswt-pi4.so at org.eclipse.swt.internal.Library.loadLibrary(Library.java:346) at org.eclipse.swt.internal.Library.loadLibrary(Library.java:255) at org.eclipse.swt.internal.gtk.OS.<clinit>(OS.java:97) at org.eclipse.swt.internal.Converter.wcsToMbcs(Converter.java:209) at org.eclipse.swt.internal.Converter.wcsToMbcs(Converter.java:155) at org.eclipse.swt.widgets.Display.<clinit>(Display.java:169) at org.eclipse.ui.internal.Workbench.createDisplay(Workbench.java:727) at org.eclipse.ui.PlatformUI.createDisplay(PlatformUI.java:183) at org.eclipse.ui.internal.ide.application.IDEApplication.createDisplay(IDEApplication.java:182) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:125) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:136) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:402) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:651) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:588) at org.eclipse.equinox.launcher.Main.run(Main.java:1459) at org.eclipse.equinox.launcher.Main.main(Main.java:1432)
05-27
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值