菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
424
0

Java实现调用高德地图逆地理编码-htmlunit

原创
05/13 14:22
阅读数 52929

使用htmlunit方式模拟页面点击操作

 

1、准备:高德地图key申请,参考高德地图KEY申请。在高德地图官网找到需要实现的功能代码。这里测试的是“逆向地理编码方法”;

2、pom.xml文件导入相关包:

 1 <dependency>
 2     <groupId>net.sourceforge.htmlunit</groupId>
 3     <artifactId>htmlunit</artifactId>
 4     <version>2.23</version>
 5 </dependency>
 6 <dependency>
 7     <groupId>net.sourceforge.htmlunit</groupId>
 8     <artifactId>htmlunit-core-js</artifactId>
 9     <version>2.23</version>
10 </dependency>

3、因为使用Java调用,只需要实现将经纬度转换成地址的功能,所以我们新建一个简单的html页面,不需要地图加载。

  代码如下:(其中 <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=xxxxxxxxxxxxxx&plugin=AMap.Geocoder"></script> 中的key为您自己申请的key

 1 <!doctype html>
 2 <html lang="en">
 3 <html>
 4 <head>
 5     <meta charset="UTF-8">
 6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 7     <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
 8     <title>逆地理编码(经纬度->地址)</title>
 9     <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
10     <style>
11         .btn{
12             width:10rem;
13             margin-left:6.8rem;
14         }
15     </style>
16 </head>
17 <body>
18 <div class="input-card" style='width:28rem;position: absolute;left: 40%;bottom: auto;top: 40%;'>
19     <label style='color:grey'>逆地理编码,根据经纬度获取地址信息</label>
20     <div class="input-item">
21         <div class="input-item-prepend"><span class="input-item-text">经纬度</span></div>
22         <input id='lnglat' type="text" value='116.39,39.9'>
23     </div>
24     <div class="input-item">
25         <div class="input-item-prepend"><span class="input-item-text" >地址</span></div>
26         <input id='address' type="text" value="" >
27     </div>
28     <input id="regeo" type="button" class="btn" value="经纬度 -> 地址" >
29 </div>
30 <script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script>
31 <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=xxxxxxxxxxxxxx&plugin=AMap.Geocoder"></script>
32 <script type="text/javascript">
33     var geocoder = new AMap.Geocoder();
34     function regeoCode() {
35         var lnglat  = document.getElementById('lnglat').value.split(',');
36         geocoder.getAddress(lnglat, function(status, result) {
37             if (status === 'complete'&&result.regeocode) {
38                 var address = result.regeocode.formattedAddress;
39                 document.getElementById('address').value = address;
40             }else{
41                 log.error('根据经纬度查询地址失败')
42             }
43         });
44     }
45     document.getElementById("regeo").onclick = regeoCode;
46     document.getElementById('lnglat').onkeydown = function(e) {
47         if (e.keyCode === 13) {
48             regeoCode();
49             return false;
50         }
51         return true;
52     };
53 </script>
54 </body>
55 </html>

4、页面测试成功后,使用htmlunit模拟页面点击。我自己封装了工具类,代码如下:

 

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.SilentCssErrorHandler;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlButtonInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import java.io.IOException;
public class AmapUtil {
    private static String url = "上面html的地址";
    private static WebClient webClient = new WebClient(BrowserVersion.CHROME);
    private static HtmlPage page;
    private static HtmlTextInput textField;
    private static HtmlButtonInput button;

    static {
        /* *****配置webClient******/
        //ajax
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());
        //支持js
        webClient.getOptions().setJavaScriptEnabled(true);
        //忽略js错误
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        //忽略css错误
        webClient.setCssErrorHandler(new SilentCssErrorHandler());
        //不执行CSS渲染
        webClient.getOptions().setCssEnabled(false);
        //超时时间
        webClient.getOptions().setTimeout(3000);
        //允许重定向
        webClient.getOptions().setRedirectEnabled(true);
        //允许cookie
        webClient.getCookieManager().setCookiesEnabled(true);
        //自定义JavaScript解析器(目的是为了不打印js存在的错误到日志)
        webClient.setJavaScriptEngine(new MyJavaScriptEngine(webClient));

        //开始请求网站
        try {
            page = webClient.getPage(url);
            textField = (HtmlTextInput) page.getElementById("lnglat");
            button = (HtmlButtonInput) page.getElementById("regeo");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String getAddress(String lnglat){
        try  {
            textField.setText(lnglat);
            button.click();
            return  ((HtmlTextInput)page.getElementById("address")).getText();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}

 自定义JavaScript解析器:

import com.gargoylesoftware.htmlunit.InteractivePage;
import com.gargoylesoftware.htmlunit.ScriptException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.JavaScriptErrorListener;
import com.gargoylesoftware.htmlunit.javascript.host.Window;

/**
 * 自定义JavaScript解析器(目的是为了不打印js存在的错误到日志)
 */
public class MyJavaScriptEngine extends JavaScriptEngine{
    public MyJavaScriptEngine(WebClient webClient) {
        super(webClient);
    }
    @Override
    protected void handleJavaScriptException(final ScriptException scriptException, final boolean triggerOnError) {
        // Trigger window.onerror, if it has been set.
        final InteractivePage page = scriptException.getPage();
        if (triggerOnError && page != null) {
            final WebWindow window = page.getEnclosingWindow();
            if (window != null) {
                final Window w = (Window) window.getScriptableObject();
                if (w != null) {
                    try {
                        w.triggerOnError(scriptException);
                    }
                    catch (final Exception e) {
                        handleJavaScriptException(new ScriptException(page, e, null), false);
                    }
                }
            }
        }
        final JavaScriptErrorListener javaScriptErrorListener = getWebClient().getJavaScriptErrorListener();
        if (javaScriptErrorListener != null) {
            javaScriptErrorListener.scriptException(page, scriptException);
        }
        if (getWebClient().getOptions().isThrowExceptionOnScriptError()) {
            throw scriptException;
        }
    }
}
View Code

5、编写测试类测试:

    @Test
    public void test22(){
        System.out.println(AmapUtil.getAddress("116.39,36.9"));
        System.out.println(AmapUtil.getAddress("115.39,36.9"));
        System.out.println(AmapUtil.getAddress("116.39,35.9"));
        System.out.println(AmapUtil.getAddress("116.39,37.9"));
        System.out.println(AmapUtil.getAddress("116.93,37.9"));
    }

  结果如下:

 

   测试成功。HtmlUnit是用Java写的无界面的浏览器,因为没有界面,因此执行的速度还可以,它提供了一系列的API,如表单的填充,表单的提交,模仿点击链接等。操作起来还是比较方便的。

 

发表评论

0/200
424 点赞
0 评论
收藏