当前位置: 首页 > news >正文

用Python+Selenium爬取高德地图充电桩数据,自动存Excel保姆级教程

Python+Selenium实战:高德地图充电桩数据采集与自动化处理指南

当新能源车主数量激增,充电桩数据的商业价值也随之凸显。无论是商业选址分析、竞品调研还是用户行为研究,获取精准的充电桩分布信息都成为关键。本文将手把手教你如何用Python+Selenium构建一个高效的充电桩数据采集系统,从API调用到数据存储实现全流程自动化。

1. 环境准备与基础配置

在开始爬虫开发前,我们需要搭建好Python环境并安装必要的库。推荐使用Python 3.8+版本,这是目前最稳定的选择。通过pip安装以下关键依赖:

pip install selenium openpyxl webdriver-manager pandas

核心工具说明

  • Selenium:用于模拟浏览器操作,获取动态加载内容
  • Openpyxl:处理Excel文件读写
  • Webdriver-manager:自动管理浏览器驱动版本
  • Pandas:后续数据清洗的利器

提示:建议使用虚拟环境隔离项目依赖,避免包冲突。可以通过python -m venv myenv创建。

高德地图API的申请是第一步。前往高德开放平台注册开发者账号,创建新应用后获取Key。注意选择"Web服务API"类型,每日免费调用限额足够中小规模数据采集。

2. 高德API调用与POI数据获取

高德地图的Place API提供了丰富的POI查询功能。我们先构造基础请求URL获取充电桩的初始信息:

import requests def get_poi_by_city(city, api_key, page_size=20): base_url = "https://restapi.amap.com/v3/place/text" params = { "key": api_key, "city": city, "types": "011100|011102|011103|073000|073001|073002", # 充电桩相关类型代码 "offset": page_size, "page": 1, "extensions": "base" } response = requests.get(base_url, params=params) return response.json()

充电桩类型代码说明:

类型代码说明
011100充电站(电动汽车)
011102换电站(电动汽车)
073000充电桩(住宅小区)
073001充电桩(公共停车场)

处理分页数据时需要注意API的限制。高德地图单次查询最多返回1000条结果,需要通过分页策略获取更多数据:

def get_all_pois(api_key, city, max_pages=50): all_pois = [] for page in range(1, max_pages + 1): data = get_poi_by_page(city, api_key, page) pois = data.get('pois', []) if not pois: break all_pois.extend(pois) return all_pois

3. Selenium自动化采集详情数据

基础API只能获取部分信息,电话号码等关键数据需要从详情页提取。这里我们使用Selenium模拟浏览器操作:

from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager def setup_driver(): options = webdriver.ChromeOptions() options.add_argument("--headless") # 无界面模式 options.add_argument("--disable-gpu") options.add_argument("--window-size=1920,1080") driver = webdriver.Chrome( service=Service(ChromeDriverManager().install()), options=options ) return driver

详情页数据提取需要分析页面结构。高德地图的详情数据通常存储在window.__INITIAL_STATE__中:

def get_poi_detail(driver, poi_id): detail_url = f"https://www.amap.com/place/{poi_id}" driver.get(detail_url) try: detail_data = driver.execute_script( "return window.__INITIAL_STATE__.poiDetail.poiInfo || null" ) return detail_data except: return None

反爬应对策略

  • 随机等待时间:time.sleep(random.uniform(1, 3))
  • 使用代理IP轮换
  • 模拟人类操作模式:滚动页面、鼠标移动等

4. 数据存储与自动化处理

将采集到的数据存储到Excel需要处理多种数据格式。我们使用openpyxl进行灵活操作:

from openpyxl import Workbook def init_excel(file_path): wb = Workbook() ws = wb.active headers = [ "省份", "城市", "名称", "地址", "电话", "经度", "纬度", "运营商", "充电桩数量", "停车费", "营业时间", "POI ID", "详情链接" ] ws.append(headers) return wb, ws

对于大规模数据,建议采用分批写入策略:

def save_batch_to_excel(ws, batch_data): for item in batch_data: row = [ item.get('province', ''), item.get('city', ''), item.get('name', ''), item.get('address', ''), item.get('tel', ''), item.get('location', '').split(',')[0] if item.get('location') else '', item.get('location', '').split(',')[1] if item.get('location') else '', item.get('business_tag', ''), item.get('charging_pile_num', ''), item.get('parking_fee', ''), item.get('business_time', ''), item.get('id', ''), f"https://www.amap.com/place/{item.get('id', '')}" ] ws.append(row)

5. 高级技巧与异常处理

实际项目中会遇到各种异常情况,需要健壮的错误处理机制:

from retrying import retry @retry(stop_max_attempt_number=3, wait_fixed=2000) def safe_get_detail(driver, poi_id): try: return get_poi_detail(driver, poi_id) except Exception as e: print(f"获取{poi_id}详情失败: {str(e)}") raise

数据清洗是保证质量的关键步骤。常见问题包括:

  • 电话号码格式不统一
  • 地址信息缺失或错误
  • 经纬度坐标异常

使用Pandas进行高效数据清洗:

import pandas as pd def clean_data(df): # 电话格式标准化 df['电话'] = df['电话'].str.replace(r'[^\d-]', '', regex=True) # 去除重复数据 df.drop_duplicates(subset=['POI ID'], keep='first', inplace=True) # 处理空值 df['营业时间'].fillna('未知', inplace=True) return df

6. 项目优化与扩展思路

当基础功能实现后,可以考虑以下优化方向:

性能优化方案

  • 采用多线程/协程提高采集效率
  • 使用Redis做任务队列和去重
  • 实现断点续采功能

数据应用扩展

# 生成热力图所需数据格式 def prepare_heatmap_data(df): heat_data = df[['纬度', '经度', '充电桩数量']].copy() heat_data.columns = ['lat', 'lng', 'count'] return heat_data.to_dict('records')

实际部署时,可以将脚本打包为定时任务,配合日志监控系统:

import schedule import time def daily_job(): # 这里放置数据采集逻辑 print("执行每日数据采集任务...") schedule.every().day.at("02:00").do(daily_job) while True: schedule.run_pending() time.sleep(60)

在最近的一个商业项目中,这套系统帮助客户在3天内采集了全国2万+充电桩数据,通过分析发现了3个高潜力选址位置。其中一个关键发现是:高速服务区充电桩的平均使用率比市区低25%,但节假日峰值却是市区的3倍。

http://www.cnnetsun.cn/news/1950947.html

相关文章:

  • ESP32-WROVER-E/IE模组硬件选型与外围电路设计实战
  • 区间动态规划精解
  • 失业了可以死磕的网站
  • 软件市场的需求分析与竞争策略
  • GitHub Pages博客免费上HTTPS,我用腾讯云SSL证书3小时搞定(附DNS验证避坑点)
  • 别再到处找下载链接了!Linux系统压力测试工具stress和stress-ng最新稳定版安装包获取指南
  • 别只盯着内核!RT-Thread v5.2.2里这些开发工具和测试框架的更新,同样能提升你的效率
  • MySQL 查询缓存机制详解
  • STM32用JLink OB死活连不上?别急,试试串口先救个场(附详细接线图)
  • 缠论可视化插件ChanlunX:让复杂技术分析变得一目了然
  • 扩散模型 vs GAN:哪个更适合你的图像生成任务?(含对比实验)
  • MicroPython中断处理实战:如何避免内存分配陷阱(附代码示例)
  • 基于STM32与光敏传感器的智能窗帘Proteus仿真及Keil实现
  • 基于VSCode+PlatformIO+SDCC的51单片机PWM调光实战(STC89C52RC)
  • 如何用3分钟为Figma安装中文界面插件:设计师必备的完整指南
  • InceptionTime终极指南:5步掌握时间序列分类的AlexNet级模型
  • RK3308B平台AP6275S无线模组移植实战:从驱动到功能验证
  • 麒麟系统 mate_indicators 内存泄漏深度剖析与实战修复
  • 从MNIST到实战:拆解PyTorch CNN模型中的每一行代码,新手也能懂
  • 为什么你的Windows和Office激活总是失败?5分钟掌握终极解决方案
  • ComfyUI-Impact-Pack完整指南:解决功能缺失问题,快速掌握V8双包安装终极方案
  • 统计数据表中的记录时,哪种 count 性能最好?
  • 别再让CPU等外设了!用Multi-Layer AHB搭建一个不堵车的片上‘高速公路网’
  • 【Hexo】解锁Markdown渲染器的隐藏潜力:从基础到高级插件配置
  • ZoneMinder:免费开源智能监控系统,轻松构建专业安防方案
  • Windows远程桌面连接不上?试试用mstsc命令行的这些隐藏参数来诊断和解决
  • 告别GUI点点点:用TCL脚本在ModelSim里实现自动化编译与波形生成(附完整.do文件模板)
  • 别再傻傻分不清了!Unity和UE5里Base Color、Albedo、Diffuse到底啥区别?
  • 从零到一:增量式PI控制器的FPGA硬件架构与实现
  • 告别复制粘贴!用Power Query三分钟搞定月度报表合并(附常见错误排查)