本案例由於google每天每個賬戶能post20000次所以我們需要相對較長的時間來抓去google的數據信息。
主要思路:通過一定的zoom一個相對較大的zoom。我們盡可能的搜索我們的所有數據。 之后我們獲取google的搜索數據如下圖

我們要抓去的就是上面的小紅點了。 我這邊抓去全國的小區信息用一台服務器跑了20天左右將全國的小區信息基本上都抓到了。 小到縣 鎮 的小區信息也抓到了。 相對還是比較理想。當時分析消耗了大量的時間。 由於我需要獲取這個小區名稱以及地圖的坐標點所以這塊還是有一定的分析的技術含量的。
抓去的數據不是只有 一個頁面我們需要post分頁抓去。這點需要注意。代碼當時只是比較簡單的處理。 注重的是過程就不上傳了。 給大家提供一些思路。
我們需要定義2個非常主要的google的url這兩個是我們獲取地址信息以及經緯度信息的關鍵點。
private string areaStr = "http://mt0.google.com/vt/pt?lyrs=m%40215000000&las={0}%3B{1}%3B{2}%3B{3}&z=14&ptv=1";
private string areaInfoStr = "http://mt0.google.com/vt/ft?lyrs=lmq:1000:%E5%B0%8F%E5%8C%BA|cc:CN|h:a|s:109146043351405611748|xc:14&las={0}&z=15&gl=cn&hl=zh-CN&xc=1";

程序的主要思路是將整個中國的范圍包含在我們設置的區域里。 之后就程序自動拖動獲取小區信息。 在抓去詳細信息。
private void GetAraeInfo(string araeCode) { int zoom = 18; var objPar = new object[3]; objPar[0] = this.currentPointF.X; objPar[1] = this.currentPointF.Y; objPar[2] = zoom; wbGoogle.Document.InvokeScript("SetCenter", objPar); var latlngArr = wbGoogle.Document.InvokeScript("GetBounds").ToString().Split(','); this.subX = double.Parse(latlngArr[0]) - double.Parse(latlngArr[2]); this.subY = double.Parse(latlngArr[1]) - double.Parse(latlngArr[3]); string url = string.Format(areaStr, latlngArr[2], latlngArr[3], latlngArr[0], latlngArr[1]); GetInfo(url, araeCode); bool flag = false; while (true) { if (this.currentPointF.X > this.rightBottomPointF.X) { this.currentPointF.X = this.currentPointF.X - this.subX; } else { if (flag) { break; } this.currentPointF.Y = this.currentPointF.Y + this.subY; this.currentPointF.X = this.leftTopPointF.X; if (this.currentPointF.Y > this.rightBottomPointF.Y) { flag = true; } } //地圖設置中心點 objPar[0] = this.currentPointF.X; objPar[1] = this.currentPointF.Y; objPar[2] = zoom; Console.WriteLine("X:" + this.currentPointF.X + " Y:" + this.currentPointF.Y); wbGoogle.Document.InvokeScript("SetCenter", objPar); latlngArr = wbGoogle.Document.InvokeScript("GetBounds").ToString().Split(','); url = string.Format(areaStr, latlngArr[2], latlngArr[3], latlngArr[0], latlngArr[1]); GetInfo(url, araeCode); Thread.Sleep(0); Application.DoEvents(); } }
獲取html數據信息當然也是少不了的。
public static String GetHtml(string url) { try { HttpWebRequest req = HttpWebRequest.Create(url) as HttpWebRequest; req.Timeout = 30 * 1000; req.Method = "get"; req.ContentType = "application/x-www-form-urlencoded"; req.Accept = "*/*"; req.Headers.Add(HttpRequestHeader.AcceptLanguage, "zh-CN"); req.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)"; HttpWebResponse response = req.GetResponse() as HttpWebResponse; Stream stream = response.GetResponseStream(); MemoryStream buffer = new MemoryStream(); Byte[] temp = new Byte[4096]; int count = 0; while ((count = stream.Read(temp, 0, 4096)) > 0) { buffer.Write(temp, 0, count); } return System.Text.Encoding.GetEncoding("utf-8").GetString(buffer.GetBuffer());//.UTF8.GetString(); } catch { return String.Empty; } }
private void GetInfo(string url, string araeCode) { string html = GetHtml(url); if (string.IsNullOrWhiteSpace(html)) return; html = html.Substring(7, html.Length - 7); int index = html.IndexOf("]}"); var javascript = new JavaScriptSerializer(); html = html.Substring(0, index);//},{ var a = html.Split(','); List<area> areaLst = new List<area>(); for (int i = 0; i < a.Length; i = i + 5) { area area = new area(); area.id = a[i].Substring(5, a[i].Length - 6); area.zrange = a[i + 1] + a[i + 2]; area.layer = a[i + 3]; area.epoch = a[i + 4]; areaLst.Add(area); } foreach (var item in areaLst) { string tmpurl = string.Format(areaInfoStr, item.id); string insertHtml = GetHtml(tmpurl); string tmp = insertHtml; string baseStr = string.Empty; int indexTitle = tmp.IndexOf("base:"); if (indexTitle != -1) { tmp = tmp.Substring(indexTitle + 6, tmp.Length - indexTitle - 6); indexTitle = tmp.IndexOf("]"); if (indexTitle != -1) { baseStr = tmp.Substring(0, indexTitle); tmp = tmp.Substring(indexTitle, tmp.Length - indexTitle); } } List<AreaInfo> strLst = new List<AreaInfo>(); while (true) { AreaInfo areaInfo = new AreaInfo(); areaInfo.Offset = baseStr; areaInfo.AreaCode = araeCode;//行政區划碼 areaInfo.ID = Guid.NewGuid(); string aStr = string.Empty; indexTitle = tmp.IndexOf("a:"); if (indexTitle != -1) { tmp = tmp.Substring(indexTitle + 3, tmp.Length - indexTitle - 3); indexTitle = tmp.IndexOf("]"); if (indexTitle != -1) { aStr = tmp.Substring(0, indexTitle); areaInfo.InnerOffset = aStr; tmp = tmp.Substring(indexTitle, tmp.Length - indexTitle); } } indexTitle = tmp.IndexOf("title:"); if (indexTitle != -1) { tmp = tmp.Substring(indexTitle + 6, tmp.Length - indexTitle - 6); //獲取小區信息 indexTitle = tmp.IndexOf(","); if (indexTitle != -1) { string araeName = tmp.Substring(0, indexTitle).Replace("\\", "").Replace("\"", ""); areaInfo.Name = araeName; if (!strLst.Exists(p => p.Name == araeName)) { strLst.Add(areaInfo); //lsvAreaInfo.Items.Add(araeName); } tmp = tmp.Substring(indexTitle, tmp.Length - indexTitle); } } else { break; } Thread.Sleep(0); Application.DoEvents(); } Application.DoEvents(); Thread.Sleep(0); } }
至此我們就可以通過代碼來獲取google地圖中你需要獲取的信息。 此案例為獲取全國小區信息。 當然我們需要獲取其他查詢的信息也是可行的。 具體的數據分析我並沒用測試。但是原理應該是一樣的。希望對你有幫助。
當然我的這個抓去時間主要是由於google的單用戶訪問次數有關。 可以購買相關的google產品獲取想要的數據。
