java中从高德地图爬取数据
1、最近一个人负责公司的一个app项目开发,需要从高德地图爬取杭州市全部的超市信息,放入mongodb的数据库中。做地理位置查询。(mongodb这部分有时间补上)
首先去高德地图创建一个开发者账号,获取一个开发web服务的高德key.这个是必须要有的,可以用我这个从百度到的key试一下
2、废话不说了直接上代码
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by cw on 2017/8/29.
*
*/
public class AddressLngLatExchange {
private static final String KEY = "389880a06e3f893ea46036f030c94700";
private static final String OUTPUT = "JSON";
private static final String GET_LNG_LAT_URL = "http://restapi.amap.com/v3/geocode/geo";
private static final String GET_LNG_PIO_URL = "http://restapi.amap.com/v3/place/polygon";
private static final Logger LOGGER = LoggerFactory.getLogger(AddressLngLatExchange.class);
//获取指定地点经纬度
public static String[] getLngLatFromOneAddr(String address){
if(StringUtils.isBlank(address)) {
LOGGER.error("地址(" + address + ")为null或者空");
return null;
}
Map<String, String> params = new HashMap<String, String>();
params.put("address", address);
params.put("output", OUTPUT);
params.put("key", KEY);
String result = HttpUtils.URLPost(GET_LNG_LAT_URL,params,"");
JSONObject jsonObject = JSONObject.parseObject(result);
String[] lngLatArr = new String[2];
//拿到返回报文的status值,高德的该接口返回值有两个:0-请求失败,1-请求成功;
int status = Integer.valueOf(jsonObject.getString("status"));
if(status == 1) {
JSONArray jsonArray = jsonObject.getJSONArray("geocodes");
for(int i = 0; i < jsonArray.size(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
String lngLat = json.getString("location");
lngLatArr = lngLat.split(",");
}
} else {
String errorMsg = jsonObject.getString("info");
LOGGER.error("地址(" + address + ")" + errorMsg);
}
return lngLatArr;
}
public static List<Shop> initialData(String lonLat, String keyword, List<Shop> shopListSon){
if(StringUtils.isBlank(keyword)) {
LOGGER.error("地址(" + keyword + ")为null或者空");
}
Map<String, String> params = new HashMap<String, String>();
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
params.put("polygon", lonLat);//"118.21,29.11;120.30,30.33"
params.put("output", OUTPUT);
params.put("keywords", keyword);
params.put("offset", "20");
params.put("page", "1");
params.put("key", KEY);
String result = HttpUtils.URLGet(GET_LNG_PIO_URL,params,"UTF-8");
JSONObject jsonObject = JSONObject.parseObject(result);
int statusOne = Integer.valueOf(jsonObject.getString("status"));
//第一次获取数据时做的判断
if(statusOne==1){
int count=Integer.valueOf(jsonObject.getString("count"));
int pageNumber=count/20;
int remainder=count%20;
if(remainder>0)pageNumber=pageNumber+1;
for(int i=1;i<=pageNumber;i++){
params.put("page", String.valueOf(i));
result = HttpUtils.URLGet(GET_LNG_PIO_URL,params,"UTF-8");
JSONObject jsonObject2 = JSONObject.parseObject(result);
System.out.println("+++++++++"+result);
//拿到返回报文的status值,高德的该接口返回值有两个:0-请求失败,1-请求成功;
int status = Integer.valueOf(jsonObject2.getString("status"));
if(status == 1) {
JSONArray jsonArray = jsonObject2.getJSONArray("pois");
if(jsonArray.size()>0){
for(int j =0;j<jsonArray.size();j++){
Shop shop =new Shop();
JSONObject jsonObject1 =jsonArray.getJSONObject(j);
shop.setShopName(jsonObject1.getString("name"));
shop.setSpecificAddress(jsonObject1.getString("address"));
shop.setId(jsonObject1.getString("id"));
String [] initLonLat =jsonObject1.getString("location").split(",");
shop.setLongitude(initLonLat[0]);
shop.setLatitude(initLonLat[1]);
shopListSon.add(shop);
//DBObject doci = new BasicDBObject("shopId", "300"+i).append("shopName", "人生得意"+i).append("shopStatus",0).append("specificAddress","天堂"+i).append("gps", new Point(new Position(lon, lat)));
}
}
} else {
String errorMsg = jsonObject.getString("info");
LOGGER.error("地址(" + keyword + ")" + errorMsg);
}
}
}
return shopListSon;
}
具体代码请去博客内查看,这里被字数限制了.
3、由于高德地图对他的数据做了保护,我这边采用的是矩形搜索。 百度到杭州的经纬度划分成多个小矩形,然后调用高德地图的API服务。我这边将爬取的数据写入excel表格中,一是为了展示验证数据是否准确,二是怕直接写入会不会有内存泄漏问题。我上面的代码有写入excel和读取excel的代码。不过要注意一下 我用得jar包不同。写入用的poi,读取用的是jxl.
4、这边调用http请求是客户端,请去博客内查看,这里被字数限制了.
5、maven里的配置
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
6、最后给大家看一下我爬取出来的数据.
如果有什么不对的地方,希望大家指点一二.
