8

我需要解析页面,除了页面上的某些元素是动态加载的之外,一切都很好。我将 jsoup 用于静态元素,然后当我意识到我真的需要动态元素时,我尝试了 javafx。我在 stackoverflow 上阅读了很多答案,并且有很多使用 javafx WebEngine 的建议。所以我以这段代码结束。

@Override
public void start(Stage primaryStage) {
    WebView webview = new WebView();
    final WebEngine webengine = webview.getEngine();
    webengine.getLoadWorker().stateProperty().addListener(
            new ChangeListener<State>() {
                public void changed(ObservableValue ov, State oldState, State newState) {
                    if (newState == Worker.State.SUCCEEDED) {
                        Document doc = webengine.getDocument();
                        //Serialize DOM
                        OutputFormat format    = new OutputFormat (doc); 
                        // as a String
                        StringWriter stringOut = new StringWriter ();    
                        XMLSerializer serial   = new XMLSerializer (stringOut, format);
                        try {
                            serial.serialize(doc);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        // Display the XML
                        System.out.println(stringOut.toString());
                    }
                }
            });
    webengine.load("http://detail.tmall.com/item.htm?spm=a220o.1000855.0.0.PZSbaQ&id=19378327658");
    primaryStage.setScene(new Scene(webview, 800, 800));
    primaryStage.show();
} 

我从 org.w3c.dom.Document 制作了字符串并打印出来。但这也没用。primaryStage.show() 向我展示了完全加载的页面(我需要在页面上呈现的元素),但在 html 代码中没有我需要的元素(在输出中)。

这是我在这个问题上工作的第三天,当然缺乏经验是我的主要问题,但我不得不说:我被困住了。这是我读完java完整参考后的第一个java项目。我这样做是为了获得一些现实世界的经验(并且是为了好玩)。我想制作中文“ebay”的解析器。

这是问题和我的测试用例:

http://detail.tmall.com/item.htm?spm=a220o.1000855.0.0.PZSbaQ&id=19378327658 需要动态加载折扣“129.00”

http://item.taobao.com/item.htm?spm=a230r.1.14.67.MNq30d&id=22794120348 需要“15.20”

如您所见,如果您首先使用浏览器查看此页面,您会看到原价,然后大约一秒钟后会看到折扣。

甚至有可能从 html 页面获得这种动态折扣吗?我需要解析的其他元素是静态的。接下来要尝试什么:另一个使用 javascript 或其他方式呈现 html 的库?我真的需要一些建议,不想放弃。

4

2 回答 2

1

Worker.State.SUCCEEDED应该已经被javascript处理后返回的DOM模型。

您的代码通过 FX 7u40 和 8.0 dev 测试对我有用。我在日志中看到下一个输出:

<DIV id="J_PromoBox"><EM class="tb-promo-price-type">夏季新品</EM><EM class="tm-yen">¥</EM>    
<STRONG class="J_CurPrice">129.00</STRONG></DIV>

这是动态加载的带有129.00您要查找的数据 () 的框。

您可能希望将 JDK 升级到 7u40 或重新访问您的日志解析算法。

于 2013-08-05T09:11:56.427 回答
0

听起来您想要在页面上的 Javascript 完成修改原始 HTML 之后从动态页面呈现 DOM。这在 Java 中并不容易,因为您需要使用嵌入式 Javascript 引擎实现类似浏览器的功能。如果您只关心从 Java 读取网页,您可能需要研究Selenium,因为它控制浏览器并允许您将呈现的 HTML 拉入 Java。

这个答案也可能有帮助:

在(任何)Java 程序中渲染 JavaScript 和 HTML(Access 渲染的 DOM 树)?

于 2013-08-03T14:05:26.030 回答