htmlunit扒取JS加载之后的网页源码(2)——解决带参、中文乱码和转义问题

今天继续来说昨天的话题——htmlunit扒取JS加载之后的网页源码

首先纠正昨天的一个错误:

原文:“而htmlunit只能返回URL对应的页面,所以我无法将htmlunit的URL指向SpringMVC的controller”
这是错误的,htmlunit可以模拟浏览器运行,也就是说它可以按controller返回的view经试图解析到达对应的页面并返回页面信息。
昨天代码导致这个问题的原因在controller的使用上,我把test这个controller作为入口,在其中调用htmlunit的方法去加载对应的url,而又愚蠢的把url之向了test这个controller,这似乎成了一个循环吧。

今天,纠正了这个错误。
解决方法,使用了两个controller,一个作为入口调用htmlunit方法,另一个作为htmlunit指向的url,其返回试图为需要扒取的工程内jsp。
这样就很好的解决了这个问题。
之前也尝试了一个controller,作为入口调用htmlunit方法,而直接把url指向了页面,这样做固然不会报错,但是不符合我的使用场景。同时无法取到该controller赋给session的值。

另外,今天解决了html带参传递的方法。

具体如下:

  WebClient wc = new WebClient(BrowserVersion.INTERNET_EXPLORER_8);  

    wc.getOptions().setUseInsecureSSL(true);  
    wc.getOptions().setJavaScriptEnabled(true); // 启用JS解释器,默认为true  
    wc.getOptions().setCssEnabled(false); // 禁用css支持  
    wc.getOptions().setThrowExceptionOnScriptError(false); // js运行错误时,是否抛出异常  
    wc.getOptions().setTimeout(100000); // 设置连接超时时间 ,这里是10S。如果为0,则无限期等待  
    wc.getOptions().setDoNotTrackEnabled(false);  
//        wc.getOptions().setActiveXNative(true);
    HtmlPage page;
    try {
         byte[] responseContent = null;  
        URL url = new URL(path);  
        WebRequest webRequest = new WebRequest(url, HttpMethod.POST);  
        List<NameValuePair> reqParam = new ArrayList<NameValuePair>();  


        reqParam.add(new NameValuePair("username", templateContent)); 
        webRequest.setCharset("utf-8");
        webRequest.setRequestParameters(reqParam);  
        page = wc.getPage(webRequest);
        WebResponse webResponse = page.getWebResponse();  
        int status = webResponse.getStatusCode();  
        System.out.println("Charset : " + webResponse.getContentCharset());  
        System.out.println("ContentType : " + webResponse.getContentType());  
        // 读取数据内容  
        if (status==200) {  
            if (page.isHtmlPage()) {  
                System.out.println("htmlPage");
                // 等待JS执行完成,包括远程JS文件请求,Dom处理  
                 wc.waitForBackgroundJavaScript(10000);    
                 responseContent = ((HtmlPage) page).asXml().getBytes();
            } else {  
                System.out.println("不是htmlPage");
                InputStream bodyStream = webResponse.getContentAsStream();  
                responseContent = ByteStreams.toByteArray(bodyStream);  
                bodyStream.close();  
            }  
        }  
        // 关闭响应流  
        webResponse.cleanUp();  
      String strToHtml = strToHtml(new String(responseContent));
      //保存为本地html文档
      File file = new File("D:/zzc.html");
      FileWriter fileWriter = new FileWriter(file);
      BufferedWriter writer = new BufferedWriter(fileWriter);
      fileWriter.write(strToHtml);      
      writer.close();

        System.out.println("GET :  " + strToHtml);
    } catch (FailingHttpStatusCodeException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }  

通过post传的值在页面可以直接使用EL表达式得到。

需要注意的是:

1、转义字符:在返回xml、html等格式文件时,其中的部分字符会被转义,出现类似&lt、&gt等形式的符号,这不是乱码,是字符转义了。
解决方法:
1- 所有在标签中的文本都不会被转义。
2- 获得转义之后的文本,在对转译字符进行替换。

public   String   strToHtml(String   s){   
    if   (s==null||s.equals("")) 
        return   "";   
    s   =   s.replaceAll("&amp;","&");   
    s   =   s.replaceAll("&lt;","<");   
    s   =   s.replaceAll("&gt;",">");   
    s   =   s.replaceAll("&nbsp;","   ");   
    s   =   s.replaceAll("<br/>","\n");   
    s   =   s.replaceAll("&#39","'");   
    s   =   s.replaceAll("&quot;", "'");
        return   s;   
}   

2、htmlunit通过带参POST出现参数中文乱码的
只需要在POST之前设置他的request请求字符编码即可。如:

webRequest.setCharset("utf-8");

亲测,直接webclient.getpage(URL)得到的HTMLPAGE不会乱码,但是不能传参。

猜你喜欢

转载自blog.csdn.net/weixin_39389850/article/details/78912982