当前位置:   article > 正文

Python爬虫实战系列6:高德地图充电站数据采集_充电站数据爬虫

充电站数据爬虫

一、分析需求

本次实验案例是采集地图APP上的充电站数据,为了演示方便,这里只展示一些基础字段采集。

首先分析网页版数据请求 https://amap.com/ 发现代码写完后,反爬措施比较厉害,频繁出现滑块验证码,可能这是阿里系的特点吧。

所以后来不得不采用直接调用高德API的形式获取poi列表

二、代码实现

2.1、获取POI列表

直接在高德开放平台注册账号,开通一个应用,个人免费版,申请key即可。

经过查看文档,我们采用搜索POI2.0接口

API文档地址:https://lbs.amap.com/api/webservice/guide/api-advanced/newpoisearch

官方文档比较详细,根据文档写对应请求代码即可。



import json

import requests


class GaodeAPI:
    """
    高德API接口版本
    """

    def __init__(self, key, city='北京', keyword=None):
        self.key = key
        self.keyword = keyword
        self.city = city
        self.offset = 20

    def get_poi_total_list(self):
        """
        获取POI列表
        :return:
        """
        first_page = self.get_poi_page(pagenum=1)
        if first_page['infocode'] == '10044':
            raise Exception('当日查询已限额,请明天再试.')
        page_count = int(first_page['count'])
        iterate_num = round(page_count / self.offset) + 1
        final_result = []
        for i in range(1, iterate_num):
            temp_result = self.get_poi_page(i)
            final_result.extend(temp_result['pois'])

        return final_result

    def get_poi_page(self, pagenum):
        """
        获取POI详情
        :param pagenum:
        :return:
        """
        url = f'https://restapi.amap.com/v3/place/text?city={self.city}&offset={self.offset}&page={pagenum}&key={self.key}&types=011100|011102|011103|073000|073001|073002&extensions=all'

        response = requests.get(url)
        result = json.loads(response.text)

        return result
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

通过以上代码可以获取到POI列表,这里解释下POI就相当于地图上任意一个点,在地图APP上,一个外卖店,洗车店,充电桩都是一个个点,这些点在地图APP上的概念叫POI。*

不管对不对,总之我是这么理解的~ *

2.2、获取POI详情

我们获取到所有POI后,接下来需要获取POI的详细信息,这个我在官方文档中没找到详情接口,所以采用别的方案实现。

通过分析web端浏览器请求明显看出请求的详情接口

浏览器地址:https://amap.com/place/B0JU3U634F place后面的是POI的id

详情接口:https://amap.com/detail/get/detail?id=B0JU3U634F

但是如果你写代码访问的时候就会出现哎哟喂,被挤爆啦,请稍后重试的错误

{'ret': ['FAIL_SYS_USER_VALIDATE', 'RGV587_ERROR::SM::哎哟喂,被挤爆啦,请稍后重试'],
  • 1

好像这个接口风控比较厉害,只能请求一次,如果仔细逆向分析估计也能解决,但是太费时费力了,并且后续还会有滑块验证码的问题需要解决。

这里推荐另外一种技术方案:既然浏览器打开网页可以请求到数据,那就监听浏览器请求包,从请求包里获取数据内容

纵观Python的这些库,没找到几个可以监听浏览器请求的库,最后还是采用国人开发的drissionpage来实现。

文档地址:https://www.drissionpage.cn/ChromiumPage/listener/#-listenwait

代码如下:

   ``def handle_detail(poi_list):`    `"""`    `处理POI详情信息`    `:return:`    `"""`    `try:`        `base_url = "https://amap.com/place/"``   `        `page = ChromiumPage()`        `page.get(base_url)  # 访问网址,这行产生的数据包不监听``   `        `page.listen.start('amap.com/detail/get/detail')  # 开始监听,指定获取包含该文本的数据包`        `for poi in poi_list:`            `poi_id = poi['id']`            `page.get(base_url + poi_id)`            `res = page.listen.wait()  # 等待并获取一个数据包`            `detail_json = res.response.body`            `detail_json = detail_json['data']`            `db.update(table='gaode_pois',`                      `data={'detail_json_data': json.dumps(detail_json)},`                      `condition=f" poi_id = '{poi_id}'"`                      `)`            `Print.green(f"{poi_id}详细信息采集完成.")``   `    `except Exception as e:`        `print(e)``   
  • 1

以上代码则实现了获取POI列表和POI详情的数据,我们把这两个json格式数据存入数据库即可。

三、导出数据

获取到数据后就简单了,直接写个函数导出Excel方便分析。

   ``def to_excel():`    `"""`    `导出Excel`    `:return:`    `"""`    `detail_list = db.query("select poi_id,detail_json_data,create_time from gaode_pois")`    `result = []`    `for detail in detail_list:`        `detail_json_data = json.loads(detail['detail_json_data'])``   `        `poi_id = detail['poi_id']`        `create_time = detail['create_time']`        `city_name = detail_json_data['base']['city_name']`        `name = detail_json_data['base']['name']`        `address = detail_json_data['base']['address']`        `brand_desc = detail_json_data['charging']['brand_desc']`        `charge_price = detail_json_data['charging']['charge_price']`        `price_parking = detail_json_data['deep']['price_parking']`        `result.append({`            `'city_name': city_name,`            `'poi_id': poi_id,`            `'name': name,`            `'address': address,`            `'brand_desc': brand_desc,`            `'charge_price': charge_price,`            `'price_parking': price_parking,`            `'create_time': create_time,`        `})`    `df = pd.DataFrame(result)`    `df.columns = ['城市', 'id', '名称', '地址', '品牌', '价格', '价格标记', '采集时间']`    `output_path = f"高德导出数据_{get_now_time()}.xlsx"`    `df.to_excel(output_path, index=False)`    `Print.green(f"数据导出完成:{output_path}")``   
  • 1

最终导出结果如下:

总结

1.阿里系的产品基本都有风控,且滑块都基本长一个样,虽然滑块看起来简单(往右一滑的样子)但是不管你怎么滑,都很难滑过。感觉这滑块就是个小游戏~2.爬虫过程中,也可以多想想其他解决方案,比如监听浏览器数据包。

由于信息安全问题,这里不放完整源码。本文章内容及代码只做学习交流使用,作者不负责任何由此引起的任何法律责任。您在引用该代码时代表您已同意该协议,由此引起的任何法律责任由您承担。

关于Python学习指南

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/728840

推荐阅读
相关标签