最近工作需要整理了一些百度地图接口查询北京住宅小区的相关信息。该篇文章主要从如下3个方面的说明:Web服务API -地点检索服务、需求分析 和 PYTHON实现 。
Web服务API -地点检索服务:
链接:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi
![1059d5cf3447a968ed6d4a81647cfd80.png](https://img-blog.csdnimg.cn/img_convert/1059d5cf3447a968ed6d4a81647cfd80.png)
API接口服务
该服务提供多种场景的地点(POI)检索功能,包括行政区划区域检索、圆形区域检索、矩形区域检索。开发者可通过接口获取地点(POI)基础或详细地理信息。
- 行政区划区域检索:检索某一行政区划内(目前最细到城市级别)的地点信息。
- 圆形区域检索:设置圆心和半径,检索圆形区域内的地点信息(常用于周边检索场景)。
- 矩形区域检索:设置检索区域左下角和右上角坐标,检索坐标对应矩形内的地点信息(常用于手机或PC端地图视野内检索)
- 地点详情检索:不同于以上三种检索功能。地点详情检索针对指定POI,检索其相关的详情信息。开发者可以通过三种区域检索(或其他服务)功能,获取POI id。使用“地点详情检索”功能,传入id,即可检索POI详情信息,如评分、营业时间等(不同类型POI对应不同类别详情数据)。
需求分析
需求内容:抓取全北京的住宅小区的数据,通过分析接口有单次返回记录数 和 最大分页为20的限制,因此采用 矩形区域检索 来抓取相关数据。
![49ee2b648e4e64478fc4992073959245.png](https://img-blog.csdnimg.cn/img_convert/49ee2b648e4e64478fc4992073959245.png)
矩形区域检索请求接口:http://api.map.baidu.com/place_abroad/v1/search?query=房地产&page_size=10&page_num=0&scope=2&bounds=35.66597,139.797339,35.677669,139.813544&output=json&ak={您的密钥} //GET请求
该接口重点输入参数:
- query:检索关键字。周边检索和矩形区域内检索支持多个关键字并集检索,不同关键字间以$符号分隔,最多支持10个关键字检索。如:”银行$酒店”。
- page_size:单次召回POI数量,默认为10条记录,最大返回20条。多关键字检索时,返回的记录数为关键字个数*page_size。
- scope:检索结果详细程度。取值为1 或空,则返回基本信息;取值为2,返回检索POI详细信息
- bounds:检索矩形区域,多组坐标间以","分隔
- 其他参数见接口规范。
PYTHON代码实现
首先将北京划分成40*40 的栅格,一个一个栅格进行数据抓取,再通过解析获取最终数据。
![ba70b880f4cf1123ef7f8c812b45bfac.png](https://img-blog.csdnimg.cn/img_convert/ba70b880f4cf1123ef7f8c812b45bfac.png)
具体代码实现如下:
# -*- coding: utf-8 -*-import numpy as np # 导入数值计算扩展模块import pandas as pdimport requests # 导入网页请求模块import time, mathunit = 40 #40*40个栅格lat_partion = [round(x,6) for x in list(np.linspace(39.340000,41.180000, unit))] # 维度划分,保留6位小数lng_partion = [round(y,6) for y in list(np.linspace(115.420000,117.500000, unit))] # 经度划分,保留6位小数community_data_list = []def get_community(): # 自定义按区域获取小区名称的函数 for i in range(7, 39): # 横向栅格索引 # time.sleep(10) for j in range(0, 39): # 纵向栅格索引 not_max_page = True # 没有到达最大页面时循环 page_num = 0 # 从第一页开始 while not_max_page: url = "http://api.map.baidu.com/place/v2/search?query=房地厂&scope=2&page_size=20&page_num=" + str(page_num) + " &bounds=" + str(lat_partion[i]) + "," + str(lng_partion[j])+"," + str(lat_partion[i+1]) + "," + str(lng_partion[j+1]) + "&output=json&ak={您的密钥}" # 构造请求网址,其中你的ak是你要向百度申请的密钥 header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'} # 构造请求头 response = requests.get(url, headers = header) # 发出请求 time.sleep(1) print(str(lat_partion[i]) ,str(lng_partion[j]), str(lat_partion[i+1]) , str(lng_partion[j+1])) answer = response.json() # json化 total = int(answer["total"]) max_page = math.ceil(total / 20) if answer['status'] == 0: # 如果正常返回 print("# Rectangle (%d,%d) Page %s" % (i, j, page_num)) print("# Amount: %s" % len(answer['results'])) print("# Total: %s" % total) page_num += 1 if page_num > max_page: # 到达最大页时推出循环到下一个单元 break for k in range(len(answer['results'])): try: province = answer['results'][k]['province'] # 省份 if province != "北京市": break city = answer['results'][k]['city'] # 城市 area = answer['results'][k]['area'] # 区域 uid = answer['results'][k]['uid'] # 唯一标识 community = answer['results'][k]['name'] # 小区名称 try: street_id = answer['results'][k]['street_id'] # 街道ID except KeyError: street_id = "" address = answer['results'][k]['address'] # 地址 lat = answer['results'][k]['location']['lat'] # 纬度 lng = answer['results'][k]['location']['lng'] # 经度 try: detail = answer['results'][k]['detail_info']['tag'] # 小区类型 except KeyError: detail = "" community_data = [province, city, area, uid,community, address,street_id,lat, lng, detail] # 组成一条记录 community_data_list.append(community_data) print(community_data) except KeyError: pass else: print("* The rectangle (%d,%d) contains no community"%(i, j)) break return community_data_list data_tmp = get_community()data = pd.DataFrame(data_tmp)data.columns = ['省份','城市','区域','唯一标识','小区名称','地址','纬度','经度','小区类型']
后续将介绍如何获取该小区的边界及小区面积计算。