根据关键字获取高德地图poi信息

百度地图和高德地图都提供了根据关键字获取相应的poi信息的api,不过它们提供给普通开发者使用的次数有限无法满足要求。其次百度地图返回的poi中位置信息不是经纬度,而高德地图则可以返回poi的经纬度信息。

网页分析

  • 目的
    以关键字怡景中心城为例,我们需要使用爬虫获取到高德地图返回的所有相关poi信息,本例中主要获取poi的名称和经纬度信息。

  • url分析
    通过chrome浏览器的监控,最终找到查询结果是通过json的形式返回,请求链接是
http://ditu.amap.com/service/poiInfo?query_type=TQUERY&pagesize=20&pagenum=1&qii=true&cluster_state=5&need_utd=true&utd_sceneid=1000&div=PC1000&addr_poi_merge=true&is_classify=true&zoom=17&city=440300&geoobj=114.056908%7C22.531457%7C114.062058%7C22.539831&keywords=%E6%80%A1%E6%99%AF%E4%B8%AD%E5%BF%83%E5%9F%8E

url中的keywords就是查询的关键字,pagenum页面数。此外经过分析发现返回结果包含20个poi信息,基本上覆盖了关键字区域,本篇博客仅爬取第一页的poi,如果想获取后续的poi,可以通过设置pagenum取值来得到。

poi信息包含在返回的joson数据中的poi_list字段

  • 请求头构建

代码

class CrawlerGaoDe(object):
    main_url = 'http://ditu.amap.com/service/poiInfo?query_type=TQUERY&pagesize=20&pagenum=1' \
               '&qii=true&cluster_state=5&need_utd=true&utd_sceneid=1000&div=PC1000&addr_poi_merge' \
               '=true&is_classify=true&zoom=16&city=440300&geoobj=114.044736%7C22.550641%' \
               '7C114.055035%7C22.567386&keywords={0}'
    def __init__(self, zone_name, proxy=None):
        self.__zone_name = zone_name
        if proxy is None:
            self.__proxy = None
        else:
            self.__proxy = {'http': proxy}

    def __init_crawler_args(self):
        '''
        初始化爬虫参数
        :return: 
        '''
        #   构造请求头
        User_Agent = 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 ' \
                     'Mobile/13B143 Safari/601.1'
        Host = 'ditu.amap.com'
        Accept = '* / *'
        Accept_Encoding = 'gzip, deflate'
        Accept_Language = 'en - US, en;q = 0.8, zh - CN;q = 0.6, zh;q = 0.4'
        amapuuid = 'b51b4430 - 611e-421e - b5f0 - d4c0069ec83a'
        Connection = 'keep - alive'
        cookie = 'guid=62e9-7327-26e6-8630; UM_distinctid=15bf554ac5ce3-07d1fa60bf59d3-24414032-' \
                 'cfcd8-15bf554ac5d163; _uab_collina=149446962066263280256309; passport_log' \
                 'in=ODY0OTIzNTQsYW1hcEF1SUZSNU45MiwyN2ZiY2x4YjJicWN3NGZjb29qYWtuYTY4bjhpdDEzN' \
                 'iwxNTA1Nzg4MDYzLE1XUm1OVE5oTlRRMk5tTmpOVEkwWWpWaU1EZzFNamRqTkdaaU5USmlabVk9; dev' \
                 '_help=A31pORob9CZKI7Sru%2B22%2FGUwNWY0ZTEyMDMwOGZiZWIyMTUyNDg3N2M5NzdiNGY3NzVhNGF' \
                 'iNDg5YzhjNjgzYmM5YjY5OTdmNjkxNjFlY2Y5%2BkDeYKdIYyjlQUymTgzjEbGZZwvhQT7HDehSDAbU71%' \
                 '2BgMgS1RZws1VsgIqQbVPGtHubQVNo3jkPiGQcc4GgNzC%2BXgQLxYhEc7WDMILJBY%2FJWXDmjfTh8Wf8e' \
                 'bkfF3VY%3D; key=bfe31f4e0fb231d29e1d3ce951e2c780; cna=HV1zEVpxFzkCATr4tPxil0OM; isg=At7' \
                 'eZS1TC8m1jV8txoi1zUMNL33gNqN9in7_KohnSiEcq36F8C_yKQRJwY1Y; CNZZDATA1255626299=593' \
                 '918092-1494468489-http%253A%252F%252Fwww.amap.com%252F%7C1505808643'
        header = {}
        header['User-Agent'] = User_Agent
        header['Host'] = Host
        header['Accept'] = Accept
        header['Accept-Encoding'] = Accept_Encoding
        header['Accept-Language'] = Accept_Language
        header['amapuuid'] = amapuuid
        header['Connection'] = Connection
        header['cookie'] = cookie
        self.__header = header
        self.__url = self.main_url.format(self.__zone_name)

    def __get_context_info(self):
        '''
        从高德地图爬取信息
        :return: 
        '''
        #   获取爬虫返回信息
        req = requests.get(self.__url, headers=self.__header, proxies=self.__proxy)
        # print req.json()
        self.__context = req.json()

    def __resolve_context(self):
        '''
        解析查询到的文本
        :return: 
        '''
        #   信息解析,保存poi名称和经纬度
        pois = self.__context['data']['poi_list']
        records = list()
        for poi in pois:
            tmp = {'zone_name': self.__zone_name, 'disp_name': poi['disp_name'],
                   'lng': float(poi['longitude']), 'lat': float(poi['latitude'])}
            records.append(tmp)
        return records
    def do(self):
        '''
        执行
        :return: 
        '''
        self.__init_crawler_args()
        self.__get_context_info()
        return self.__resolve_context()


if __name__ == '__main__':
    #   单个关键字查询
    craw_gaode = CrawlerGaoDe('怡景中心城', None)
    records = craw_gaode.do()
    print records
    pd.DataFrame.from_records(records).to_csv('/home/用户名/Desktop/test.txt', encoding='utf-8', index=False)

上述爬虫中可以添加代理ip,输出结果如下:

disp_name	lat	lng	zone_name
怡景中心城	22.535799	114.05976	怡景中心城
怡景中心城停车场(出入口)	22.536416	114.059332	怡景中心城
怡景中心城广场停车场(出口)	22.536433	114.060231	怡景中心城
怡景中心城小天才专柜	22.535086	114.059913	怡景中心城
藤蔓慕果(怡景中心城店)	22.5358	114.05976	怡景中心城
中心城广场停车场(出入口)	22.536676	114.059312	怡景中心城
Miss南(怡景中心城店)	22.53511	114.059967	怡景中心城
麦当劳(怡景中心城店)	22.535774	114.0591	怡景中心城
汕头外砂乌弟卤鹅(怡景中心城店)	22.535729	114.059093	怡景中心城
家乐福(中心城店)	22.536266	114.059923	怡景中心城
陈钢串串香(怡景中心城店)	22.535411	114.05912	怡景中心城
指典世家(怡景中心城店)	22.5344	114.059681	怡景中心城
AT.PINK.CO(怡景中心城店)	22.536248	114.059305	怡景中心城
特斯拉充电站(ipower15私驾护理中心怡景中心城店)	22.536396	114.059341	怡景中心城
杂咖(怡景中心城)	22.535469	114.060467	怡景中心城
反斗乐园(怡景中心城)	22.535394	114.059777	怡景中心城
卫生间(怡景中心城)	22.536489	114.059134	怡景中心城
卫生间(怡景中心城)	22.535927	114.059091	怡景中心城
卫生间(怡景中心城)	22.536392	114.060427	怡景中心城
卫生间(怡景中心城)	22.535931	114.06033	怡景中心城

 posted on 2017-09-19 17:09  暴走小飞鼠  阅读(2061)  评论(2编辑  收藏  举报