如何使用htmlunit在iframe中打印外部脚本?

时间:2014-07-08 12:27:30

标签: java iframe htmlunit

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.SilentCssErrorHandler;
import com.gargoylesoftware.htmlunit.ThreadedRefreshHandler;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.html.HtmlPage;    
public class ReadHtml{
       public static void main(String[] args) throws Exception {
java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(java.util.logging.Level.OFF);
    WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24);
    webClient.getOptions().setJavaScriptEnabled(true);
    webClient.getOptions().setActiveXNative(true);
    webClient.getOptions().setAppletEnabled(false);
    webClient.getOptions().setCssEnabled(true);
    webClient.getOptions().setDoNotTrackEnabled(true);
    webClient.getOptions().setGeolocationEnabled(false);
    webClient.getOptions().setPopupBlockerEnabled(false);
    webClient.getOptions().setPrintContentOnFailingStatusCode(true);
    webClient.getOptions().setThrowExceptionOnFailingStatusCode(true);
    webClient.getOptions().setThrowExceptionOnScriptError(true);
    webClient.setAjaxController(new NicelyResynchronizingAjaxController());
    webClient.setCssErrorHandler(new SilentCssErrorHandler());
    webClient.setRefreshHandler(new ThreadedRefreshHandler());
    webClient.getCookieManager().setCookiesEnabled(true);
    WebRequest request = new WebRequest(new URL("some url containing javascript to load html elements"));
    try {
            Page page;
            page = webClient.getPage(request);
            //System.out.println(page.getWebResponse().getContentAsString());
            System.out.println(((HtmlPage) page).asXml());
    } catch (FailingHttpStatusCodeException e) {
            e.printStackTrace();
    } catch (IOException e) {
            e.printStackTrace();
    }
}
}

我想打印所有html元素(不仅是源代码),包括由javascript,iframe,嵌套iframe生成的html。我试过这个代码,但(也尝试通过id识别,但不喜欢打印任何特定的。想要打印整个HTML内容),通过javascript加载的html不打印到控制台。有人可以指出需要进行修改吗? 提前谢谢。

2 个答案:

答案 0 :(得分:2)

我为我的任务找到了一些解决方案(不完全是我想要的)

List<WebWindow> windows = webClient.getWebWindows();
for(WebWindow w : windows){
        HtmlPage hpage2 = (HtmlPage) w.getEnclosedPage();
        System.out.println("-------------------------------------");
        System.out.println(hpage2.asXml());
}

通过这种方式,我可以获得所有iframe内容和嵌套的iframe内容。不是连续页面,而是单独。

当我知道iframe名称时,我可以通过

提取该内容
HtmlPage hpage = (HtmlPage)webClient.getWebWindowByName("google_esf").getEnclosedPage();

现在这解决了我的问题。如果有人建议如何获得连续页面,那就更好了。

答案 1 :(得分:0)

尝试使用page.asXML。

HTMLPage本身是一个DOM节点,因此您可以递归地遍历子节点。可以通过DOM或通过page.getFrames(递归)访问这些帧。

如果需要打印来自服务器的所有响应,可以使用WebConnectionWrapper作为拦截器。这将使您可以访问所有响应(包括脚本)


7月9日

框架是DOM的一部分。但是,如果某些内容是异步加载的(Ajax),HTMLUnit可能不会等待加载。尝试将AjaxController添加到WebClient。 Here就是一个例子。

对于WebConnectoinWrapper,请使用this示例。但同样,如果有一些异步处理,HTMLUnit可能会在所有处理完成之前退出。所以,AjaxController可能是你最好的选择。

browser.setWebConnection(new WebConnectionWrapper(browser) {
  public WebResponse getResponse(final WebRequest request) throws IOException {
    WebResponse response = super.getResponse(request);
    //processResponse
    return response;
 }
});

7月10日

NicelyResynchronizingAjaxController适用于用户启动的ajax。对于“自我加载”,尝试这样的事情。

public class AlwaysSynchronizingAjaxController extends NicelyResynchronizingAjaxController {
public boolean processSynchron(HtmlPage page, WebRequest settings, boolean async) {
    return true;
};
}

如果您正在使用Fiddler(或wireshark或任何其他嗅探/拦截工具),请查看您是否找到了动态加载请求的通信。