获取百度地图POI数据三(模拟关键词搜索)

上一篇博文中讲到如何获取用于搜索的关键词,并且已经准备好了一百五十万的关键词   这其中有门牌号码,餐馆酒店名称,公司名称,道路名称等。有了这些数据,我们就可以通过代码,模拟我们在百度地图的搜索框中搜索地点,从而获取其返回的POI数据。下面直接上代码~

一 、准备好用于存储数据的数据库表

  

由于百度返回的POI数据都是JSON字符串且子节点非常多,为了按照子节点一一存储,就需要建这么一张包含很多字段的表,虽然麻烦,但是信息很全面。当然各位也可以选择性的存储其中的数据。

  二、获取并解析数据的代码

class Program
    {
        static string[] strArr = { "name", "addr", "address_norm", "alias", "aoi", "area_name", "brand_id", "cla", "di_tag", "ext_display", "geo", "indoor_pano", "navi_update_time", "new_catalog_id", "primary_uid", "show_tag", "std_tag", "storage_src", "street_id", "tag", "tel", "uid" };
        static string[] flaArr = { "navi_x", "navi_y" };
        static string[] intArr = { "acc_flag", "area", "biz_type", "catalogID", "click_flag", "detail", "diPointX", "diPointY", "dis", "dist2route", "dist2start", "ext_type", "f_flag", "father_son", "flag_type", "geo_type", "ismodified", "pano", "poiType", "poi_click_num", "poi_profile", "prio_flag", "route_flag", "status", "ty", "view_type", "x", "y" };
        static List<string> tempList = new List<string>();
        static void Main(string[] args)
        {       //调用SQLHelper类中的方法
            DataTable kwDt = SQLHelper.ExecuteDataTable("select KWName from SHKW order by SaveTime", CommandType.Text);
            List<string> kwList = new List<string>();
            foreach (DataRow row in kwDt.Rows)
            {
                kwList.Add(row["KWName"].ToString());
            }
            int total = kwList.Count;
            DataTable tempDt = SQLHelper.ExecuteDataTable("select name,addr from SHPOI", CommandType.Text);
            foreach (DataRow row in tempDt.Rows)
            {
                tempList.Add(row["name"].ToString() + "," + row["addr"].ToString());
            }
            for (int i = 0; i < kwList.Count; i++)
            {
                string kw = kwList[i];
                string keyWord = "上海市" + kw;
                for (int j = 0; j < 200; j++)
                {
                    string url = "http://map.baidu.com/?newmap=1&reqflag=pcmap&biz=1&from=webmap&da_par=direct&pcevaname=pc4.1&qt=s&da_src=searchBox.button&wd=" + keyWord + "&c=289&pn=" + j;
                    int count = DownloadPOIInfoFromBMap(url, -1, keyWord + j);
                    if (count == -1) break;
                    Console.WriteLine("成功写入数据:" + count + "条  执行次数:" + (j + 1) + "  KeyWord:" + keyWord + " kwNum:" + (kwList.IndexOf(kw) + 1) + " tatal:" + total);
                }
            }
            Console.WriteLine("ok");
            Console.ReadKey();
        }
        private static int DownloadPOIInfoFromBMap(string url, int typeId, string fileName)
        {
            int count = 0;
            Stream responseStream;
            string restring;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                responseStream = response.GetResponseStream();
                StreamReader sr = new StreamReader(responseStream, Encoding.Default);
                restring = sr.ReadToEnd();
            }
            catch
            {
                Console.WriteLine("网络异常");
                return count;
            }
            string[] strArr = restring.Split(new string[] { "\\u" }, StringSplitOptions.None);
            StringBuilder sb = new StringBuilder();
            sb.Append(strArr[0]);
            try
            {
                for (int i = 1; i < strArr.Length; i++)
                {
                    string code = strArr[i];
                    int value = Convert.ToInt32(code.Substring(0, 4), 16);
                    sb.Append(char.ConvertFromUtf32(value));
                    if (code.Length > 4)
                    {
                        sb.Append(code.Substring(4, code.Length - 4));
                    }

                }
            }
            catch
            {
                return count;
            }
            JObject jo;
            try
            {
                jo = (JObject)JsonConvert.DeserializeObject(sb.ToString());
            }
            catch
            {         //一些数据无法正确转换为json对象  需要特别处理
                Regex regex = new Regex("\"\\{\\\\\"index_tag\\\\\".*?\"\\}\"");
                //MatchCollection collection = regex.Matches(sb.ToString());
                string data = sb.ToString();
                data = regex.Replace(data, "\"\"");
                try
                {
                    jo = (JObject)JsonConvert.DeserializeObject(data);
                }
                catch
                {
                    Regex regex1 = new Regex("\"\\{\\\\\"shop_id\\\\\".*?\"\\}\"");
                    data = regex1.Replace(data, "\"\"");
                    try
                    {
                        jo = (JObject)JsonConvert.DeserializeObject(data);
                    }
                    catch
                    {
                        try
                        {
                            Console.Write("无法构建JSON对象 ");
                            File.WriteAllText(@"D:\errorData\" + fileName + ".txt", data);
                        }
                        catch { }
                        return count;
                    }
                }
            }
            return SavePOIToDB(jo, typeId);
        }

        private static int SavePOIToDB(JObject jo, int typeId)
        {
            int count = 0;
            try
            {
                if (jo["content"].Children().Count() == 0) return -1;
            }
            catch
            {
                if (jo != null) return -1;

            }
            foreach (JToken child in jo["content"].Children())
            {
                List<SqlParameter> listParam = new List<SqlParameter>();
                foreach (string s in strArr)
                {
                    listParam.Add(new SqlParameter(@s, GetInfoString(s, child)));
                }
                foreach (string f in flaArr)
                {
                    listParam.Add(new SqlParameter(@f, GetInfoString(f, child)));
                }
                foreach (string i in intArr)
                {
                    listParam.Add(new SqlParameter(@i, GetInfoString(i, child)));
                }
                List<float> coordinate = ConvertCoor(GetInfoInt("x", child), GetInfoInt("y", child));
                listParam.Add(new SqlParameter(@"TypeId", typeId));
                listParam.Add(new SqlParameter(@"lot_bdll", coordinate[0]));
                listParam.Add(new SqlParameter(@"lat_bdll", coordinate[1]));
                string tempStr = GetInfoString("name", child).Replace("‘", "") + "," + GetInfoString("addr", child);
                if (tempList.Contains(tempStr)) continue;
                tempList.Add(tempStr);
                string sql = "insert into SHPOI values(@Name,@acc_flag,@addr,@address_norm,@alias,@aoi,@area,@area_name,@biz_type,@brand_id,@catalogID,@cla,@click_flag,@detail,@diPointX,@diPointY,@di_tag,@dis,@dist2route,@dist2start,@ext_display,@ext_type,@f_flag,@father_son,@flag_type,@geo,@geo_type,@indoor_pano,@ismodified,@navi_update_time,@navi_x,@navi_y,@new_catalog_id,@pano,@poiType,@poi_click_num,@poi_profile,@primary_uid,@prio_flag,@route_flag,@show_tag,@status,@std_tag,@storage_src,@street_id,@tag,@tel,@ty,@uid,@view_type,@x,@y,@lot_bdll,@lat_bdll,@TypeId)";
                SQLHelper.ExecuteNonQuery(sql, CommandType.Text, listParam.ToArray());
                count++;
            }
            return count;
        }
        private static int GetInfoInt(string key, JToken jo)
        {
            try
            {
                return Convert.ToInt32(jo[key].ToString());
            }
            catch
            {
                return 0;
            }
        }

        private static float GetInfoFloat(string key, JToken jo)
        {
            try
            {
                return float.Parse(jo[key].ToString());
            }
            catch
            {
                return 0;
            }
        }
        private static string GetInfoString(string key, JToken jo)
        {
            try
            {
                return jo[key].ToString();
            }
            catch
            {
                return DBNull.Value.ToString();
            }
        }

        /// <summary>
        /// 将bdmac坐标转换城bdll坐标
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        private static List<float> ConvertCoor(int x, int y)
        {
            //GevTfxGlAWxzIzTobk7PGX1eu2YF0RMl
            //ghCXsfOvpXwWsnm6lhWGelF5f0Fh3y82
            List<float> list = new List<float>();
            string url = "http://api.map.baidu.com/geoconv/v1/?coords=" + x / (100.0) + "," + y / (100.0) + "&from=6&to=5&ak=ghCXsfOvpXwWsnm6lhWGelF5f0Fh3y82";
            Stream responseStream;
            StreamReader sr;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                responseStream = response.GetResponseStream();
                sr = new StreamReader(responseStream, Encoding.Default);
            }
            catch
            {
                list.Add(0);
                list.Add(0);
                return list;
            }
            string restring = sr.ReadToEnd();
            JObject jo;
            try
            {
                jo = (JObject)JsonConvert.DeserializeObject(restring);
                list.Add(float.Parse(jo["result"][0]["x"].ToString()));
                list.Add(float.Parse(jo["result"][0]["y"].ToString()));
            }
            catch
            {
                list.Add(0);
                list.Add(0);
            }
            return list;
        }
    }

使用关键词模拟百度地图的搜索功能从而获取返回的POI数据的方法能够获取大量的POI数据  由于返回的数据中没有百度经纬度坐标信息,只有百度墨卡托的坐标,所以还需要调用它的API  通过坐标转换的方方法来获取百度经纬度坐标。这就需要申请开发密钥了,而且每个密钥一天最多只能进行十万次的坐标转换。

以下是本人获取的部分POI数据:

以上就是本人获取百度地图POI数据的方式,由于关键词数量在百万级别   而且百度每次返回的数据的页数也不近相同,多的有百页,少的仅有一条设置没有,所以程序需要运行很长的时间,本人运行两周程序也才获取到一百多万数据。预计程序运行完成时POI数据总量或与关键词总量相差无几,也能达到一百五十万左右,虽然并不知道百度地图上海地区的POI数据具体有多少,但是一百多万的数据量已经能够做些分析了。

时间: 2024-10-12 13:06:13

获取百度地图POI数据三(模拟关键词搜索)的相关文章

获取百度地图POI数据二(准备搜索关键词)

上篇讲到  想要获取尽可能多的POI数据 需要准备尽可能多的搜索关键字   那么这些关键字如何得来呢?   本人使用的方法是通过一些网站来获取这些关键词   http://poi.mapbar.com/这个网站有全国各地的POI数据  对各个城市的POI数据都有归类  我便是从这个网站上面获取了上海市的各个类别的关键词  比如上海市所有的门牌号码  公路名称  地铁名称等等  下面介绍如何获取这些信息 和获取百度POI数据所用的方法一样,都是通过分析这个网站的url然后替换其中的参数获取不同的数

获取百度地图POI数据一(详解百度返回的POI数据)

POI是一切可以抽象为空间点的现实世界的实体,比如餐馆,酒店,车站,停车场等.POI数据具有空间坐标和各种属性,是各种地图查询软件的基础数据之一.百度地图作为国内顶尖的地图企业,其上具有丰富的POI数据,要获取其上的POI数据可以根据百度地图提供的API,但是这种方式有限制,能获取的数据极少.本文将详细介绍通过模拟HTTP请求的方式获取其上的POI数据. 当我们在百度地图的搜索框中通过输入关键字进行搜索时,这其实就是发送一个HTTP请求到百度的服务器,然后服务器返回数据. 打开网页的调试面板可以

百度地图POI数据爬取,突破百度地图API爬取数目“400条“的限制11。

1.POI爬取方法说明 1.1AK申请 登录百度账号,在百度地图开发者平台的API控制台申请一个服务端的ak,主要用到的是Place API.检校方式可设置成IP白名单,IP直接设置成了0.0.0.0/0比较方便. Place API 提供的接口用于返回查询某个区域的某类POI数据,且提供单个POI的详情查询服务,用户可以使用C#.C++.Java,Python等开发语言发送请求,接收json.xml的数据.关于Place API的具体使用可以参考:Place API Web服务API 1.2爬

教你如何拔取百度地图POI兴趣点

教你如何拔取百度地图POI兴趣点 通过聚合数据提供的接口,获取百度地图的POI兴趣点,并存储至数据库中. 实现: 1.聚合数据百度POI接口说明 调用聚合数据,首先得注册聚合.聚合数据提供的百度地图POI的接口有三个:数据分类,查询数据和获取周边数据.想要获取百度POI兴趣点,涉及到的接口为数据分类,查询数据. a.数据分类 接口地址:http://apis.juhe.cn/baidu/getCategory 支持格式:JSON/XML 请求方式:GET 请求示例:http://apis.juh

iOS地图集成示例:百度地图POI检索

一.集成百度地图(傻瓜教程,以网站说明文档为准,此处罗列几项主要步骤) 1.登录  http://lbsyun.baidu.com  百度地图开发者平台,获取SDK和集成文档. 2.百度地图可以提供的一些服务 (1)地图:提供地图展示和地图操作功能: (2)POI检索:支持周边检索.区域检索和城市内兴趣点检索: (3)地理编码:提供经纬度和地址信息相互转化的功能接口: (4)线路规划:支持公交.驾车.步行.骑行,四种方式的线路规划: (5)覆盖物图层:支持在地图上添加覆盖物(标注.几何图形.热力

【百度地图API】建立全国银行位置查询系统(四)——如何利用百度地图的数据生成自己的标注

原文:[百度地图API]建立全国银行位置查询系统(四)--如何利用百度地图的数据生成自己的标注 摘要: 上一章留个悬念,"如果自己没有地理坐标的数据库,应该怎样制作银行的分布地图呢?" 答案就是,利用百度地图上的数据. ---------------------------------------------------------------------------------------------- 我们不用花大把时间写代码去跑数据,只需要利用百度地图API提供的免费接口,就可以

iOS百度地图poi检索(基于百度地图2.3.0SDK开发)

正好做到百度地图的poi检索,拿来分享一下,基于百度地图2.3.0SDK开发,说实话,这个新版本poi真不好用 先来看头文件里面,定义poi对象,当然你也可以写到实现文件里面 #import <UIKit/UIKit.h> #import "BMapKit.h" @interface NearByPlaceViewController : ViewControllerBase <BMKPoiSearchDelegate> {     BMKPoiSearch *

根据城市名获取百度地图坐标API

最近项目中百度地图的相关操作当没有坐标的时候默认通过城市名称获取中心点,不过感觉有点慢到网上搜索了一下也没类似的城市对应的价格的数据库.所以自己就建了一个.现公开出来供大家使用接口调用方法 http://2.ibtf.sinaapp.com/map/?city=北京返回json串 {"x":"116.403874","y":"39.914889"} 注1.城市名请用UTF-8编码否则会出错2.如返回 please reload

一个PHP脚本,通过curl先获取百度地图api生成的经纬度,然后改数据库内的数据。

今天写一个PHP脚本,目的是让先从数据库拿取响应的地区名  然后通过幼儿园的名字来查询准确的经纬度.此间每次生成的经纬度进入数据库内的更改. 7万多条数据用时一个小时执行完毕. 不得不说 用curl结果还是比file_getcoents快的多.话不多说直接上代码 <?php date_default_timezone_set('Asia/Chongqing'); header('content-type:text/html; charset=utf-8'); ini_set('display_e