zoukankan      html  css  js  c++  java
  • 高德3地图之python爬取POI数据及其边界经纬度(根据关键字在城市范围内搜索)

    高德3地图之python爬取POI数据及其边界经纬度(根据关键字在城市范围内搜索)

    • 目前高德的边界没法批量爬取,不过可以采用百度地图的接口来替代,目前用着还可以,参见这里:

        

    • 为了方便大家,不用再为安装环境,以及运行报错等问题困扰,目前已经将POI数据爬取做成一个在线公开的数工具,地址奉上:

            

    免费使用哦,只需要申请个高德key,然后选择需要爬取的城市,关键字名,以及数据的

    背景

         由于之前项目需要从高德地图上爬取一个地方的不同分类数据,所以初学了一下爬虫,也了解了一些高德地图提供的web API用来获取免费的地图数据。因此写了一篇博客用来记录一下大致步骤。

         项目的需求是爬取一个地方的七个分类数据, 包括大学、景点、酒店等等,其中一条数据叫作一个POI。需要的poi点的字段包括:poi点id、名称name、位置(经纬度)location、所属省名称pname、所属省编号pcode、所属城市名称cityname、所属城市编号citycode、所属区名称adname、所属区编号adcode、所在地址address、所属类别type、边界经纬度。这里先展示一下最后爬取到的保存在excel表格中的数据吧。

     

    步骤说明

    1. 申请账号

    高德开放平台 | 高德地图API注册账号,并且申请web服务的AK密钥,每次发送请求需要带着这个key去认证。注册账号登陆后点击右上角的控制台 ->应用管理 -> 创建应用 -> 添加新key,注意选择web api,就得到了一个可以使用web服务的key密钥。

    2. 确定api查询的地址:

    查找高德地图提供的web api下的搜索模块,http://lbs.amap.com/api/webservice/guide/api/search 使用关键字搜索服务,关键字搜索API的服务地址:

        http://restapi.amap.com/v3/place/text?parameters

      我们需要根据API提供的参数说明拼接GET请求所需要的参数URL。常用的使用参数说明:

    key  用户在高德地图官网申请Web服务API类型KEY
    keywords 查询关键字
    types

    查询POI类型

    city 城市
    offset,page 分页参数
    output 返回数据格式类型,可选值:JSON,XML

     比如,查询珠海的所有大学数据,拼接起来完整的url:

    http://restapi.amap.com/v3/place/text?&keywords=%E5%A4%A7%E5%AD%A6&city=%E7%8F%A0%E6%B5%B7&output=json&offset=20&page=1&key=9f99fc570ccaf6abc209780433d9f4c1&extensions=all


      使用浏览器打开上面的链接,返回的数据使用hijson格式化后截图如下:

        

      其中的pois展开后就是返回的当前页的POI数据。

    3. 根据获取到的POI数据的id获取其边界经纬度

     高德地图上搜索一个景点时,如果有边界的景点会圈出其范围,如下图所示:

        

     打开F12切换到network查看,点击一下该范围,会看到发送了一个detail请求,返回了这个圈的详细信息。请求的地址如下:

    1.  
       
    2.  
      https://ditu.amap.com/detail/get/detail?id=B0014014AD

    该接口传入POI点的id,返回详细信息,我们在第二部拿到了POI点的ID,因此可以遍历每一个POI数据,然后根据id获取边界数据,获取到的detail数据格式化后如下:

    标红的shape数据即为边界坐标数据(一个多边形的边界其实是由多个点围成的)。

    解析数据

    具体代码

    getpois方法传入需要的城市名和分类关键字,最后将数据导出到d盘目录下excel文件中:

    运行代码前须知:

    • 需要将代码前面的amap_web_key的值替换为第一步中申请到的web api的密钥。
    • 需要启动爬取程序时,需要修改getpois()方法的两个参数值(代码的后部分),cityname为城市名,classfield为分类名,分类可以查看官方文档。
    • 由于高德地图每个key每天的请求量有限额,并且请求评率太快的话会返回错误信息,因此建议最好每天不要爬太多,而且不要集中在一个时间点。
    1.  
      from urllib.parse import quote
    2.  
      from urllib import request
    3.  
      import json
    4.  
      import xlwt
    5.  
       
    6.  
       
    7.  
      amap_web_key = '你申请的密钥'
    8.  
      poi_search_url = "http://restapi.amap.com/v3/place/text"
    9.  
      poi_boundary_url = "https://ditu.amap.com/detail/get/detail"
    10.  
       
    11.  
      #根据城市名称和分类关键字获取poi数据
    12.  
      def getpois(cityname, keywords):
    13.  
      i = 1
    14.  
      poilist = []
    15.  
      while True : #使用while循环不断分页获取数据
    16.  
      result = getpoi_page(cityname, keywords, i)
    17.  
      result = json.loads(result) # 将字符串转换为json
    18.  
      if result['count'] == '0':
    19.  
      break
    20.  
      poilist.extend(result['pois'])
    21.  
      i = i + 1
    22.  
      return poilist
    23.  
       
    24.  
      #数据写入excel
    25.  
      def write_to_excel(poilist, cityname, classfield):
    26.  
      # 一个Workbook对象,这就相当于创建了一个Excel文件
    27.  
      book = xlwt.Workbook(encoding='utf-8', style_compression=0)
    28.  
      sheet = book.add_sheet(classfield, cell_overwrite_ok=True)
    29.  
      #第一行(列标题)
    30.  
      sheet.write(0, 0, 'id')
    31.  
      sheet.write(0, 1, 'name')
    32.  
      sheet.write(0, 2, 'location')
    33.  
      sheet.write(0, 3, 'pname')
    34.  
      sheet.write(0, 4, 'pcode')
    35.  
      sheet.write(0, 5, 'cityname')
    36.  
      sheet.write(0, 6, 'citycode')
    37.  
      sheet.write(0, 7, 'adname')
    38.  
      sheet.write(0, 8, 'adcode')
    39.  
      sheet.write(0, 9, 'address')
    40.  
      sheet.write(0, 10, 'type')
    41.  
      sheet.write(0, 11, 'boundary')
    42.  
      for i in range(len(poilist)):
    43.  
      # 根据poi的id获取边界数据
    44.  
      bounstr =''
    45.  
      bounlist = getBounById(poilist[i]['id'])
    46.  
      if(len(bounlist) > 1):
    47.  
      bounstr = str(bounlist)
    48.  
      #每一行写入
    49.  
      sheet.write(i + 1, 0, poilist[i]['id'])
    50.  
      sheet.write(i + 1, 1, poilist[i]['name'])
    51.  
      sheet.write(i + 1, 2, poilist[i]['location'])
    52.  
      sheet.write(i + 1, 3, poilist[i]['pname'])
    53.  
      sheet.write(i + 1, 4, poilist[i]['pcode'])
    54.  
      sheet.write(i + 1, 5, poilist[i]['cityname'])
    55.  
      sheet.write(i + 1, 6, poilist[i]['citycode'])
    56.  
      sheet.write(i + 1, 7, poilist[i]['adname'])
    57.  
      sheet.write(i + 1, 8, poilist[i]['adcode'])
    58.  
      sheet.write(i + 1, 9, poilist[i]['address'])
    59.  
      sheet.write(i + 1, 10, poilist[i]['type'])
    60.  
      sheet.write(i + 1, 11, bounstr)
    61.  
      # 最后,将以上操作保存到指定的Excel文件中
    62.  
      book.save(r'd:\' + cityname +'.xls')
    63.  
       
    64.  
      #单页获取pois
    65.  
      def getpoi_page(cityname, keywords, page):
    66.  
      req_url = poi_search_url + "?key=" + amap_web_key + '&extensions=all&keywords=' + quote(keywords) + '&city=' + quote(cityname) + '&citylimit=true' + '&offset=25' + '&page=' + str(page) + '&output=json'
    67.  
      data = ''
    68.  
      with request.urlopen(req_url) as f:
    69.  
      data = f.read()
    70.  
      data = data.decode('utf-8')
    71.  
      return data
    72.  
       
    73.  
      #根据id获取边界数据
    74.  
      def getBounById (id):
    75.  
      req_url = poi_boundary_url + "?id=" + id
    76.  
      with request.urlopen(req_url) as f:
    77.  
      data = f.read()
    78.  
      data = data.decode('utf-8')
    79.  
      dataList = []
    80.  
      datajson = json.loads(data) # 将字符串转换为json
    81.  
      datajson = datajson['data']
    82.  
      datajson = datajson['spec']
    83.  
      if len(datajson) == 1:
    84.  
      return dataList
    85.  
      if datajson.get('mining_shape') != None:
    86.  
      datajson = datajson['mining_shape']
    87.  
      shape = datajson['shape']
    88.  
      dataArr = shape.split(';')
    89.  
       
    90.  
      for i in dataArr:
    91.  
      innerList = []
    92.  
      f1 = float(i.split(',')[0])
    93.  
      innerList.append(float(i.split(',')[0]))
    94.  
      innerList.append(float(i.split(',')[1]))
    95.  
      dataList.append(innerList)
    96.  
      return dataList
    97.  
       
    98.  
       
    99.  
      #获取城市分类数据
    100.  
      cityname = "珠海"
    101.  
      classfiled = "大学"
    102.  
      pois = getpois(cityname, classfiled)
    103.  
       
    104.  
      #将数据写入excel
    105.  
      write_to_excel(pois, cityname, classfiled)
    106.  
      print('写入成功')
    107.  
       
    108.  
      #根据获取到的poi数据的id获取边界数据
    109.  
      #dataList = getBounById('B02F4027LY')
    110.  
      #print(type(dataList))
    111.  
       
    112.  
      #print(str(dataList))
    113.  
      '''
    114.  
      返回的边界数据格式--方便高德地图前端展示
    115.  
      [[113.559199, 22.239364], [113.559693, 22.238274], [113.55677, 22.237162],
    116.  
      [113.557008, 22.236653], [113.555582, 22.236117], [113.555747, 22.235742],
    117.  
      [113.555163, 22.235538], [113.555027, 22.235831], [113.554934, 22.235875],
    118.  
      [113.554088, 22.235522], [113.553919, 22.235885], [113.553905, 22.235961],
    119.  
      [113.556167, 22.236835], [113.55561, 22.238172], [113.55494, 22.237933],
    120.  
      [113.554607, 22.238652], [113.554593, 22.238697], [113.554597, 22.238765],
    121.  
      [113.554614, 22.238834], [113.554646, 22.238885], [113.558612, 22.240406],
    122.  
      [113.558799, 22.240258], [113.559199, 22.239364]]
    123.  
      '''

    由于在很多情况下,只需要爬取POI点的中心坐标就行了,因此这里也提供了直接获取分类数据中心点坐标的代码,下面是爬去出来的成果截图:

    运行代码之前,需要安装xlutils库,代码如下:

    1.  
      from urllib.parse import quote
    2.  
      from urllib import request
    3.  
      import json
    4.  
      import xlwt
    5.  
       
    6.  
      amap_web_key = '你申请的web服务的密钥'
    7.  
      poi_search_url = "http://restapi.amap.com/v3/place/text"
    8.  
      poi_boundary_url = "https://ditu.amap.com/detail/get/detail"
    9.  
       
    10.  
       
    11.  
      #TODO 需要爬取的POI所属的城市名,以及分类名. (中文名或者代码都可以,代码详见高德地图的POI分类编码表)
    12.  
      cityname = "珠海"
    13.  
      classfiled = "大学"
    14.  
       
    15.  
       
    16.  
      # 根据城市名称和分类关键字获取poi数据
    17.  
      def getpois(cityname, keywords):
    18.  
      i = 1
    19.  
      poilist = []
    20.  
      while True: # 使用while循环不断分页获取数据
    21.  
      result = getpoi_page(cityname, keywords, i)
    22.  
      print(result)
    23.  
      result = json.loads(result) # 将字符串转换为json
    24.  
      if result['count'] == '0':
    25.  
      break
    26.  
      hand(poilist, result)
    27.  
      i = i + 1
    28.  
      return poilist
    29.  
       
    30.  
       
    31.  
      # 数据写入excel
    32.  
      def write_to_excel(poilist, cityname, classfield):
    33.  
      # 一个Workbook对象,这就相当于创建了一个Excel文件
    34.  
      book = xlwt.Workbook(encoding='utf-8', style_compression=0)
    35.  
      sheet = book.add_sheet(classfield, cell_overwrite_ok=True)
    36.  
       
    37.  
      # 第一行(列标题)
    38.  
      sheet.write(0, 0, 'id')
    39.  
      sheet.write(0, 1, 'name')
    40.  
      sheet.write(0, 2, 'location')
    41.  
      sheet.write(0, 3, 'pname')
    42.  
      sheet.write(0, 4, 'pcode')
    43.  
      sheet.write(0, 5, 'cityname')
    44.  
      sheet.write(0, 6, 'citycode')
    45.  
      sheet.write(0, 7, 'adname')
    46.  
      sheet.write(0, 8, 'adcode')
    47.  
      sheet.write(0, 9, 'address')
    48.  
      sheet.write(0, 10, 'type')
    49.  
      sheet.write(0, 11, 'typecode')
    50.  
      sheet.write(0, 12, 'gridcode')
    51.  
      sheet.write(0, 13, 'entr_location')
    52.  
      sheet.write(0, 14, 'timestamp')
    53.  
      sheet.write(0, 15, 'tel')
    54.  
      sheet.write(0, 16, 'postcode')
    55.  
      sheet.write(0, 17, 'tag')
    56.  
      sheet.write(1, 18, 'shopid')
    57.  
      sheet.write(1, 19, 'shopinfo')
    58.  
       
    59.  
       
    60.  
      for i in range(len(poilist)):
    61.  
      # 每一行写入
    62.  
      sheet.write(i + 1, 0, poilist[i]['id'])
    63.  
      sheet.write(i + 1, 1, poilist[i]['name'])
    64.  
      sheet.write(i + 1, 2, poilist[i]['location'])
    65.  
      sheet.write(i + 1, 3, poilist[i]['pname'])
    66.  
      sheet.write(i + 1, 4, poilist[i]['pcode'])
    67.  
      sheet.write(i + 1, 5, poilist[i]['cityname'])
    68.  
      sheet.write(i + 1, 6, poilist[i]['citycode'])
    69.  
      sheet.write(i + 1, 7, poilist[i]['adname'])
    70.  
      sheet.write(i + 1, 8, poilist[i]['adcode'])
    71.  
      sheet.write(i + 1, 9, poilist[i]['address'])
    72.  
      sheet.write(i + 1, 10, poilist[i]['type'])
    73.  
      sheet.write(i + 1, 11, poilist[i]['typecode'])
    74.  
      sheet.write(i + 1, 12, poilist[i]['gridcode'])
    75.  
      sheet.write(i + 1, 13, poilist[i]['entr_location'])
    76.  
      sheet.write(i + 1, 14, poilist[i]['timestamp'])
    77.  
      sheet.write(i + 1, 15, poilist[i]['tel'])
    78.  
      sheet.write(i + 1, 16, poilist[i]['postcode'])
    79.  
      sheet.write(i + 1, 17, poilist[i]['tag'])
    80.  
      sheet.write(i + 1, 18, poilist[i]['shopid'])
    81.  
      sheet.write(i + 1, 19, poilist[i]['shopinfo'])
    82.  
       
    83.  
       
    84.  
       
    85.  
      # 最后,将以上操作保存到指定的Excel文件中
    86.  
      book.save(r'' + cityname + "_" + classfield + '.xls')
    87.  
       
    88.  
       
    89.  
      # 将返回的poi数据装入集合返回
    90.  
      def hand(poilist, result):
    91.  
      # result = json.loads(result) # 将字符串转换为json
    92.  
      pois = result['pois']
    93.  
      for i in range(len(pois)):
    94.  
      poilist.append(pois[i])
    95.  
       
    96.  
       
    97.  
      # 单页获取pois
    98.  
      def getpoi_page(cityname, keywords, page):
    99.  
      req_url = poi_search_url + "?key=" + amap_web_key + '&extensions=all&keywords=' + quote(
    100.  
      keywords) + '&city=' + quote(cityname) + '&citylimit=true' + '&offset=25' + '&page=' + str(
    101.  
      page) + '&output=json'
    102.  
      data = ''
    103.  
      with request.urlopen(req_url) as f:
    104.  
      data = f.read()
    105.  
      data = data.decode('utf-8')
    106.  
      return data
    107.  
       
    108.  
       
    109.  
      # 获取城市分类数据
    110.  
       
    111.  
      pois = getpois(cityname, classfiled)
    112.  
       
    113.  
      # 将数据写入excel
    114.  
      write_to_excel(pois, cityname, classfiled)
    115.  
      print('写入成功')
    116.  
       

    在后面代码中,会将爬取的POI数据写入EXCEL中,EXCEL存放文件为当前目录,文件名为 cityname_classfiled.xls,例如珠海_大学.xls。

    高德地图在媒体开放日上展示了其基于大数据发现、专业采集进化的高德地图“活数据”生产能力。

    高德地图在媒体开放日上展示了其基于大数据发现、专业采集进化的高德地图“活数据”生产能力。

    高德地图技术副总裁于志杰表示,“我们正在采取一种全新的方式做地图,数亿的高德用户每天使用地图和导航服务,所以哪里的路不通了,哪里的门店关闭了,我们都可以很快知道。这些活的数据让地图开发永不停止,让地图每一秒钟都不一样。”

    据了解,高德地图自2002年开始自主采集地图数据。“高德地图自2007年开始进行了用‘活数据’生产地图的尝试,那一年我们利用实时交通大数据提供了实时路况服务。现在,活数据能力已经渗透进了高德地图生产开发的每个环节。”于志杰介绍。

    在高德地图数据中心大屏幕上展开的北京城区地图上,密密麻麻闪烁着无数移动的小点,这些都是当时在路上行驶的GPS定位回传。这些大数据首先能够使高德地图实时捕捉交通动态,实时获知各条道路的畅通情况、行驶车速、拥堵原因及事故、管制、施工等交通事件,并根据通行情况对用户的导航路线进行调整或提醒。

    据介绍,高德地图精准的实时交通大数据中有78%来自于UGC众包数据,22%来自于出租车、物流车等行业浮动车辆。高德地图的实时交通动态事件数据中,有85%来自于用户上报,其余来自于交管和政府。

    此外,高德地图还受益于阿里巴巴大数据,比如菜鸟的运单数据、物流车数据,和口碑的外卖订单数据。通过数据融合,高德方面表示可以发掘POI的新增与变化,强化地图基础数据。

    高德方面还表示,为了让专业采集员和采集设备采集的数据“活”起来,达成地图数据更新速度接近T+0(时间差为零)的目标,近年来高德地图的自主专业采集能力在三个方向上实现进化:一是在线化,二是自动化,三是智能化。同时,高德地图整个数据采集生产链条由过去的人工主导、计划式采集生产转变为由大数据、自动化主导的智能化采集调度与生产处理。

    Python对高德地图业务数据的selenium抓取,用,爬取,商家

    发表时间:2020-11-08

    注:本文仅供学习使用,请勿用于商业,如需指定类目数据请求,私信交流

    1.Selenium简介

    Selenium是一个用于测试网站的自动化测试工具,支持各种浏览器包括Chrome、Firefox、Safari等主流界面浏览器,同时也支持phantomJS无界面浏览器。

    2.支持多种操作系统 
    如Windows、Linux、Mac、Unix等。

    3.安装selenium及webdriver

    >>>#命令行下输入
    >>>pip install selenium
    >>>
    >>>webdriver请根据浏览器及版本对应关系下载
    >>>下载后请将exe文件放入有环境变量的路径下,一般放在Python目录下
    >>>如导入还有问题,请修改Python目录下对应的配置文件
    
     

    4.获取高德地图商家信息位置 
     
    在此页面可以看到请求的地址信息及方式(更多方式请自行查看),这里的Request URL地址就是我们接下来要用到的

    5.进入页面拉数据 
    在这里插入图片描述 
    由4中获取到的地址打开页面,获取页面源码,并将此段文本转换为json格式即可

    6.上源码(此为简易版)

    import json
    from selenium import webdriver
    #打开浏览器
    browser = webdriver.Chrome()
    urls = '' #自行由上面步骤获取
    browser.get(urls)
    html_source = browser.page_source
    #推出浏览器
    browser.quit()
    #因拉的源码前后有html文本,截取字符串即可
    d = json.dumps(html_source[84:-20],ensure_ascii=False)
    d1 = json.loads(d)
    #转为字典
    d2 = eval(d1)
    for i in range(len(d2['data']['poi_list'])):
    	#打印商户名称、地址、联系方式
        print([d2['data']['poi_list'][i]['name'],d2['data']['poi_list'][i]['address'],d2['data']['poi_list'][i]['tel']])
        break
    

     

    附录:

    网站:http://www.mapboxx.cn  提供的其他功能:

  • 相关阅读:
    模块化编程
    flex 弹性布局
    作用域与作用域链
    深入解读JavaScript面向对象编程实践
    javascript Null、Undefined 、NaN的联系与区别
    跨域常见解决方案
    Reverse Pairs
    315. Count of Smaller Numbers After Self
    2. Add Two Numbers
    657. Judge Route Circle
  • 原文地址:https://www.cnblogs.com/xinxihua/p/14418772.html
Copyright © 2011-2022 走看看