POI数据获取-Python

POI数据是什么?“Point of interest”的缩写,翻译为“兴趣点”。兴趣点数据可以获得研究区内的餐厅服务、风景区、交通设施等等兴趣点数据,根据这些数据可以进行城市功能区分类、快递点的时空分布特征、人口活动区等等研究,同时结合夜光数据也可进行多源数据的耦合研究。

本文为大家带来兴趣点提取的方法,其中Key需要到高德地图API账号进行申请。

申请链接:

https://console.amap.com/dev/key/app

POI分类编码下载网址:

https://lbs.amap.com/api/webservice/download

提交后即可获取第一张图所示的key

爬取代码如下:

from urllib.parse import quote
import urllib.request
import pandas as pd
import xlwt
import json
class getpoi:
  output_path = "D:/pycharm/POI/POI data/"#输出路径
  path_class = "E:/Learn/Analysis of urban ribbon/amap_poicode/amap_poicode.xlsx"#POI分类编码表位置
  amap_web_key = 'fd6043f1ad500d2b5dd40af6e555b840'#高德地图API_KEY
  poi_search_url = https://restapi.amap.com/v3/place/text?key=%s&extensions=all&keywords=&types=%s&city=%s&citylimit=true&offset=25&page=%s&output=json #申请密钥
  cityname = '北京'
  areas = ['昌平区']#如爬取整个北京市,建议分区爬取,以免出现数据量限制的问题
  totalcontent = {}
  
  def __init__(self):
    data_class = self.getclass()
    for type_class in data_class:
      for area in self.areas:
      page = 1;
      if type_class['type_num'] / 10000 < 10:
        classtype = str('0') + str(type_class['type_num'])
      else:
        classtype = str(type_class['type_num'])
      while True:
        if classtype[-4:] == "0000":
          break;
        poidata = self.get_poi(classtype, area, page);
        poidata = json.loads(poidata)
        if poidata['count'] == "0":
          break;
        else:
          poilist = self.hand(poidata)
          print("area:" + area + "  type:" + classtype + "  page:第" + str(page) + "页  count:" + poidata['count'] + "poilist:")
          page += 1
          for pois in poilist:
            if classtype[0:2] in self.totalcontent.keys():
              pois['bigclass'] = type_class['bigclass']
              pois['midclass'] = type_class['midclass']
              pois['smallclass'] = type_class['smallclass']
              list_total = self.totalcontent[classtype[0:2]]
              list_total.append(pois)
            else:
              self.totalcontent[classtype[0:2]] = []
              pois['bigclass'] = type_class['bigclass']
              pois['midclass'] = type_class['midclass']
              pois['smallclass'] = type_class['smallclass']
              self.totalcontent[classtype[0:2]].append(pois)
    for content in self.totalcontent:
      self.writeexcel(self.totalcontent[content], content)
      
#将数据写入excel
def writeexcel(self, data, classname):
  book = xlwt.Workbook(encoding='utf-8', style_compression=0)
  sheet = book.add_sheet(classname, cell_overwrite_ok=True)
  # 第一行(列标题)
  sheet.write(0, 0, 'x')
  sheet.write(0, 1, 'y')
  sheet.write(0, 2, 'count')
  sheet.write(0, 3, 'name')
  sheet.write(0, 4, 'adname')
  sheet.write(0, 5, 'smallclass')
  sheet.write(0, 6, 'typecode')
  sheet.write(0, 7, 'midclass')
  classname = data[0]['bigclass']
  for i in range(len(data)):
    sheet.write(i + 1, 0, data[i]['lng'])
    sheet.write(i + 1, 1, data[i]['lat'])
    sheet.write(i + 1, 2, 1)
    sheet.write(i + 1, 3, data[i]['name'])
    sheet.write(i + 1, 4, data[i]['adname'])
    sheet.write(i + 1, 5, data[i]['smallclass'])
    sheet.write(i + 1, 6, data[i]['classname'])
    sheet.write(i + 1, 7, data[i]['midclass'])
  book.save(self.output_path + self.cityname + '_' + classname + '.xls')


def hand(self, poidate):
  pois = poidate['pois']
  poilist = []
  for i in range(len(pois)):
    content = {}
    content['lng'] = float(str(pois[i]['location']).split(",")[0])
    content['lat'] = float(str(pois[i]['location']).split(",")[1])
    content['name'] = pois[i]['name']
    content['adname'] = pois[i]['adname']
    content['classname'] = pois[i]['typecode']
    poilist.append(content)
  return poilist


def readfile(self, readfilename, sheetname):
  data = pd.read_excel(readfilename, sheet_name=sheetname)
  return data


def getclass(self):
  readcontent = self.readfile(self.path_class, "amap_poicode")
  data = []
  for num in range(readcontent.shape[0]):
    content = {}
    content['type_num'] = readcontent.iloc[num]['NEW_TYPE']
    content['bigclass'] = readcontent.iloc[num]['大类']
    content['midclass'] = readcontent.iloc[num]['中类']
    content['smallclass'] = readcontent.iloc[num]['小类']
    data.append(content)
  return data


def get_poi(self, keywords, city, page):
  poiurl = self.poi_search_url % (self.amap_web_key, keywords, quote(city), page)
  data = ''
  with urllib.request.urlopen(poiurl) as f:
  data = f.read().decode('utf8')
  return data
if __name__ == "__main__":
gp = getpoi()

注:

1.如数据量过大,建议分区下载,避免数据量限制而无法成功下载。

2.如开发环境没有安装python相应库,可以在控制台使用pip install **的命令进行安装

提取到的数据情况如上所示。

微信公众号GIS攻略同步更新中,欢迎大家关注!!!如想直接获取北京市POI数据,公众号GIS攻略后台回复北京市POI即可。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值