总共分3步:
第一步,通过腾讯地图API收集门店地理位置数据;
第二步,将地理位置数据导入Elasticsearch;
第三步,使用Kibana绘制门店地图。
下面详细展开。
按照 WebService API 文档的步骤申请密钥,文档网址为: https://lbs.qq.com/service/webService/webServiceGuide/webServiceOverview 。
密钥申请下来:
可以将演示的密钥换成自己的Key进行测试:
https://apis.map.qq.com/ws/place/v1/search?keyword=酒店&boundary=nearby(39.908491,116.374328,1000)&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77
接下来,本人准备使用 “城市/区域搜索” 这个接口,网址:https://lbs.qq.com/service/webService/webServiceGuide/webServiceSearch 。
学习了一下请求参数,其中必填参数有3个,分别是 keyword,boundary 和 key 。另外还用到了参数 page_size 和 page_index。因为每次查询最多返回 200 条数据,在无法预估结果的情况下,本人决定逐个行政区进行查询,boundary 参数的 city_name 将使用 adcode,即行政区划代码。北京市代码如下:
这里,本人编写了一个脚本,调用 API 接口,将数据存储进 mxbc.json 文件
import requests #调用接口
import time #防止并发限制
import tqdm #查看进度
#keyword: 搜索关键字,长度最大96个字节,注:keyword仅支持检索一个。
#city_name: 检索城市名称,支持adcode(行政区划代码,可精确到区县级)
keyword = '蜜雪冰城'
city_name = ['110101','110102','110105','110106','110107','110108','110109',
'110111','110112','110113','110114','110115','110116','110117','110118','110119']
#请求函数
def base_request(city, page = 1):
url = "https://apis.map.qq.com/ws/place/v1/search?" #接口地址
params = {'keyword':keyword, #查找的关键字
'boundary':'region(' + city + ',2)', #范围
'key':'xxxxx', #你的key
'page_index':page, #显示几页
'page_size':20} #每页条目数,最大限制为20条
response = requests.get(url,params=params) #调用接口
answer = response.json() #接收返回的数据
print("%s 有 %d 家门店" %(city,answer["count"]))
f = open("./mxbc.json", "a+") #将返回结果逐行写入文件
for line_number in range(0,len(answer["data"])):
f.write(str(answer["data"][line_number]) + "\n")
f.close()
time.sleep(1)
return answer["count"] // -20 * -1 #每页条目数为20时,返回总页数
for city in tqdm.tqdm(city_name): #顺序查询各区情况,tqdm显示进度
page_index = base_request(city) #返回门店数量
if page_index > 1: #返回结果每页最多20,结果大于1页,逐页处理
for page in range(2, page_index + 1):
base_request(city, page)
else:
continue
运行效果如下:
得到的数据如下:
{'id': '17153800364953537565', 'title': '蜜雪冰城(南锣鼓巷店)', 'address': '北京市东城区鼓楼东大街164号(工商银行与穿行体育中间)', 'tel': '13520051612', 'category': '美食:冷饮店', 'type': 0, 'location': {'lat': 39.940685, 'lng': 116.400879}, 'ad_info': {'adcode': 110101, 'province': '北京市', 'city': '北京市', 'district': '东城区'}}
{'id': '7100735642175914831', 'title': '蜜雪冰城(国瑞购物中心店)', 'address': '北京市东城区崇文门外大街18号(近西花市大街)国瑞购物中心G', 'tel': '18226293405', 'category': '美食:冷饮店', 'type': 0, 'location': {'lat': 39.898211, 'lng': 116.41924}, 'ad_info': {'adcode': 110101, 'province': '北京市', 'city': '北京市', 'district': '东城区'}}
{'id': '17783258983880652103', 'title': '蜜雪冰城(簋街店)', 'address': '北京市东城区东直门内大街178号', 'tel': '17330593555', 'category': '美食:冷饮店', 'type': 0, 'location': {'lat': 39.94083, 'lng': 116.423554}, 'ad_info': {'adcode': 110101, 'province': '北京市', 'city': '北京市', 'district': '东城区'}}
{'id': '4146011748979863497', 'title': '蜜雪冰城(银河Soho商场店)', 'address': '北京市东城区南竹杆胡同2号银河Soho商场B1', 'tel': '17527357702', 'category': '美食:冷饮店', 'type': 0, 'location': {'lat': 39.921109, 'lng': 116.433767}, 'ad_info': {'adcode': 110101, 'province': '北京市', 'city': '北京市', 'district': '东城区'}}
... ...
环境:
可以使用两种方法创建索引。
第一种方法,使用 dev_tools 创建。因为本例中 Elasticsearch 是单机运行,这里使用以下命令:
PUT /mxbc
{
"settings":{
"number_of_shards" : 1,
"number_of_replicas" : 0
},
"mappings": {
"properties": {
"id":{"type":"text"},
"title":{"type":"keyword"},
"address":{"type":"text"},
"tel":{"type":"text"},
"category":{"type":"text"},
"type":{"type":"integer"},
"location" : {"type" : "geo_point"},
"adcode":{"type":"keyword"},
"province":{"type":"text"},
"city":{"type":"text"},
"district":{"type":"keyword"}
}
}
}
创建成功:
第二种方法,使用 curl 命令直接创建。使用以下命令:
curl --user 'username':'password' -X PUT "192.168.198.145:9200/mxbc2?pretty" -H 'Content-Type: application/json' -d'
{
"settings":{
"number_of_shards" : 1,
"number_of_replicas" : 0
},
"mappings": {
"properties": {
"id":{"type":"text"},
"title":{"type":"keyword"},
"address":{"type":"text"},
"tel":{"type":"text"},
"category":{"type":"text"},
"type":{"type":"integer"},
"location" : {"type" : "geo_point"},
"adcode":{"type":"keyword"},
"province":{"type":"text"},
"city":{"type":"text"},
"district":{"type":"keyword"}
}
}
}
'
创建过程如下:
两种方法最终都可以创建成功,效果如下:
为了满足 Bulk API 格式,便于批量导入,需要在每行数据前面添加 index 信息。python脚本处理一下:
f = open("./bulk.txt", "a+")
for line in open("mxbc.json"):
index = "{\"index\":{\"_index\":\"mxbc\"}}"
index = index + '\n' + line
f.write(index)
f.close()
生成文档 bulk.txt,内容为:
# head bulk.txt
{"index":{"_index":"mxbc"}}
{'id': '17153800364953537565', 'title': '蜜雪冰城(南锣鼓巷店)', 'address': '北京市东城区鼓楼东大街164号(工商银行与穿行体育中间)', 'tel': '13520051612', 'category': '美食:冷饮店', 'type': 0, 'location': {'lat': 39.940685, 'lng': 116.400879}, 'ad_info': {'adcode': 110101, 'province': '北京市', 'city': '北京市', 'district': '东城区'}}
{"index":{"_index":"mxbc"}}
{'id': '7100735642175914831', 'title': '蜜雪冰城(国瑞购物中心店)', 'address': '北京市东城区崇文门外大街18号(近西花市大街)国瑞购物中心G', 'tel': '18226293405', 'category': '美食:冷饮店', 'type': 0, 'location': {'lat': 39.898211, 'lng': 116.41924}, 'ad_info': {'adcode': 110101, 'province': '北京市', 'city': '北京市', 'district': '东城区'}}
{"index":{"_index":"mxbc"}}
{'id': '17783258983880652103', 'title': '蜜雪冰城(簋街店)', 'address': '北京市东城区东直门内大街178号', 'tel': '17330593555', 'category': '美食:冷饮店', 'type': 0, 'location': {'lat': 39.94083, 'lng': 116.423554}, 'ad_info': {'adcode': 110101, 'province': '北京市', 'city': '北京市', 'district': '东城区'}}
{"index":{"_index":"mxbc"}}
{'id': '4146011748979863497', 'title': '蜜雪冰城(银河Soho商场店)', 'address': '北京市东城区南竹杆胡同2号银河Soho商场B1', 'tel': '17527357702', 'category': '美食:冷饮店', 'type': 0, 'location': {'lat': 39.921109, 'lng': 116.433767}, 'ad_info': {'adcode': 110101, 'province': '北京市', 'city': '北京市', 'district': '东城区'}}
{"index":{"_index":"mxbc"}}
{'id': '7680346462735838662', 'title': '蜜雪冰城(东方广场店)', 'address': '北京市东城区长安街1号东方广场BB80号', 'tel': '13661055941', 'category': '美食:冷饮店', 'type': 0, 'location': {'lat': 39.909089, 'lng': 116.414132}, 'ad_info': {'adcode': 110101, 'province': '北京市', 'city': '北京市', 'district': '东城区'}}
不要忘记处理一下坐标,lng 需要变为 lon,同时单引号需要变换成双引号,否则后面无法导入:
sed -i s/lng/lon/g bulk.txt
sed -i s/\'/\"/g bulk.txt
使用命令将 bulk.txt 内数据导入 Elasticsearch:
curl --user 'username':'password' -H 'Content-Type: application/x-ndjson' -XPOST '192.168.198.145:9200/mxbc/_bulk?pretty' --data-binary @bulk.txt
Kibana 创建 Index pattern 后,可以查询到这些数据,共 199 条。
点击 Maps - Add layer - Documents,按步骤设置,即可展示门店位置
Name 命名为“门店位置”,visibility(可见度)根据需要进行设置。Label 设置为 title,可展示门店名称:
点击 Add layer - Clusters and grids,按步骤设置,即可聚合门店数量
默认按照区域内数量进行聚合:
最后放一张俯视图结束:
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/zsx0728/article/details/125348089
内容来源于网络,如有侵权,请联系作者删除!