HTML应用指南:利用POST请求获取全国小鹏汽车的充电桩位置信息

在新能源汽车快速发展的背景下,充电桩的分布和可用性成为影响用户体验的关键因素之一。随着全球对环境保护意识的增强以及政府对新能源政策的支持,越来越多的消费者倾向于选择电动汽车作为日常出行工具。然而,充电设施是否完备、便捷直接影响了用户的购车决策与使用体验。

小鹏汽车作为新能源汽车行业的重要参与者,在车辆制造和充电基础设施建设方面都做出了显著的努力。为了满足用户不断增长的需求,小鹏汽车不仅致力于提升车辆性能和技术水平,还特别关注充电网络的扩展和完善。小鹏汽车通过"自建+联盟"双轨模式打造立体补能体系,截止到2025年3月1日,小鹏自营充电网络累计上线2077座,其中小鹏超充站(S2)568座;小鹏超快充站(S4+S5)1059座;小鹏目的地站450座; 适用于车主免费充电权益站点共计2881座,其中第三方站点(免费权益可用)911座,形成"城区5公里、高速50公里"的充电服务圈。这种"全场景覆盖+极速补能"的组合策略,使其用户充电满意度达行业领先水平。

为了帮助用户更方便地找到小鹏汽车充电桩的位置,本文将探讨如何利用Python的requests库发送POST请求,从官方渠道获取充电桩位置信息,并讲解如何解析响应数据及实现数据可视化,从而分析小鹏汽车充电桩的分布情况

小鹏充电桩分布位置信息:小鹏汽车充电服务、续航能力怎么样丨小鹏汽车

我们第一步先找到门店数据的存储位置,然后看3个关键部分标头、 负载、 预览;

**标头:**通常包括URL的连接,也就是目标资源的位置;

**负载:**对于POST请求:负载通常包含了传递的参数,这里我们可以看到它的传参包括,页数和当前坐标,还是明文,没有进行加密;

**预览:**指的是对响应内容的快速查看或摘要显示,可以帮助用户快速了解返回的数据结构或内容片段;

接下来就是数据获取部分,先理解原理,完整的查询方式是通过定位坐标点查询周边20公里左右范围内小鹏充电桩的位置信息;

先讲一下方法思路,一共三个步骤;

方法思路

  1. 获取原始坐标点并在周边生成新的等距离点,生成层数可自定义;
  2. 基于去重后的新生成点进行查询,并保留查询得到的充电桩信息;
  3. 坐标转换,GCJ-02转WGS84;

**第一步:**获取原始坐标点并在周边生成新的等距离点;

**第二步:**基于去重后的新生成点进行查询,并保留查询得到的充电桩信息;

完整代码#运行环境 Python 3.11

python 复制代码
import matplotlib.pyplot as plt
import math
import numpy as np
import requests
import json
import pandas as pd
import time
import random

# 设置matplotlib支持中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号


def check_duplicate_coordinates(coordinates, precision=6):
    """检查重复的坐标点"""
    unique_coords = set()
    duplicates = []

    for lat, lng in coordinates:
        rounded_coord = (round(lat, precision), round(lng, precision))
        if rounded_coord in unique_coords:
            duplicates.append((lat, lng))
        else:
            unique_coords.add(rounded_coord)

    if duplicates:
        print(f"发现 {len(duplicates)} 个重复的坐标点:")
        for lat, lng in duplicates:
            print(f"纬度: {lat:.6f}, 经度: {lng:.6f}")
    else:
        print("未发现重复的坐标点")

    return [tuple(map(float, coord)) for coord in unique_coords]


def calculate_grid_coordinates(center_lat, center_lng, distance_km=20, layers=2):
    """生成网格状的坐标点"""
    coordinates = []

    lat_change = distance_km / 111.32
    lng_change = distance_km / (111.32 * math.cos(math.radians(center_lat)))

    for i in range(-layers, layers + 1):
        for j in range(-layers, layers + 1):
            lat = center_lat + i * lat_change
            lng = center_lng + j * lng_change
            coordinates.append((lat, lng))

    print("\n检查重复点...")
    unique_coordinates = check_duplicate_coordinates(coordinates)
    print(f"原始坐标点数量: {len(coordinates)}")
    print(f"去重后坐标点数量: {len(unique_coordinates)}")

    return unique_coordinates


def draw_circle(center_lat, center_lng, radius_km):
    """生成圆形的经纬度点"""
    theta = np.linspace(0, 2 * np.pi, 100)
    lat_change = radius_km / 111.32
    lng_change = radius_km / (111.32 * math.cos(math.radians(center_lat)))

    circle_lats = center_lat + lat_change * np.cos(theta)
    circle_lngs = center_lng + lng_change * np.sin(theta)

    return circle_lngs, circle_lats


def search_charge_stations(lat, lng):
    """查询充电站信息"""
    url = "https://chargegateway.xiaopeng.com/front/charge/station/search/queryMapLabeling"
    headers = {
        "Content-Type": "application/json",
    }
    payload = {
        "source": 2,
        "latitude": lat,
        "longitude": lng,
        "filterCriteriaCodeList": ["freeCharging"]
    }

    try:
        response = requests.post(url, headers=headers, data=json.dumps(payload))
        if response.status_code == 200:
            data = response.json()
            print(f"坐标 ({lat}, {lng}) 查询成功")
            stations = data.get('data', {}).get('result', [])
            if stations:
                print(f"找到 {len(stations)} 个充电站")
            return stations
        else:
            print(f"请求失败,状态码: {response.status_code}, 响应内容: {response.text}")
            return []
    except Exception as e:
        print(f"请求异常: {str(e)}")
        return []


def save_to_csv(stations, filename="charging_stations_info.csv"):
    """将充电站信息保存为CSV文件"""
    df = pd.DataFrame(stations)
    df.to_csv(filename, index=False, encoding='utf-8-sig')
    print(f"充电站信息已保存为 {filename}")


def visualize_grid_with_circles(center_lat, center_lng, distance_km=20, layers=2):
    """可视化网格点和它们的覆盖范围"""
    # 创建图形,设置分辨率
    plt.figure(figsize=(15, 15), dpi=100)

    coordinates = calculate_grid_coordinates(center_lat, center_lng, distance_km, layers)

    # 绘制覆盖圆和坐标点
    for lat, lng in coordinates:
        circle_lngs, circle_lats = draw_circle(lat, lng, distance_km)
        plt.plot(circle_lngs, circle_lats, 'b--', alpha=0.5)
        plt.plot(lng, lat, 'bo', markersize=8)

    # 绘制中心点
    plt.plot(center_lng, center_lat, 'ro', markersize=10, label='起始点')

    # 设置图形属性
    plt.grid(True)
    plt.xlabel('经度', fontsize=12)
    plt.ylabel('纬度', fontsize=12)
    plt.title(f'给定经纬度周围 {distance_km} 公里范围内的坐标点 (层数: {layers})',
              fontsize=14, pad=20)
    plt.legend(fontsize=10)

    # 调整坐标轴范围
    margin = distance_km / 111.32 * (layers + 1)
    plt.xlim(center_lng - margin, center_lng + margin)
    plt.ylim(center_lat - margin, center_lat + margin)

    # 保持纵横比
    plt.axis('equal')

    # 添加网格标签
    plt.grid(True, linestyle='--', alpha=0.7)
    plt.tick_params(labelsize=10)

    plt.show()


def main():
    # 参数设置
    center_lat = 31.228357
    center_lng = 121.475223
    distance_km = 20
    layers = 2

    try:
        # 1. 可视化坐标点分布
        print("正在生成坐标点分布图...")
        visualize_grid_with_circles(center_lat, center_lng, distance_km, layers)

        # 2. 获取所有坐标点
        coordinates = calculate_grid_coordinates(center_lat, center_lng, distance_km, layers)

        # 3. 查询充电站信息
        print("\n开始查询充电站信息...")
        all_stations = []
        total_points = len(coordinates)

        for i, (lat, lng) in enumerate(coordinates, 1):
            print(f"\n处理第 {i}/{total_points} 个坐标点")
            stations = search_charge_stations(lat, lng)

            if stations:
                all_stations.extend(stations)

            # 随机延时
            if i < total_points:  # 最后一个点不需要延时
                delay = random.uniform(1, 3)
                print(f"等待 {delay:.1f} 秒后继续...")
                time.sleep(delay)

        # 4. 保存结果
        if all_stations:
            print(f"\n总共找到 {len(all_stations)} 个充电站")
            save_to_csv(all_stations)

            # 打印部分充电站信息作为示例
            print("\n部分充电站信息示例:")
            for station in all_stations[:5]:  # 只显示前5个
                print(f"充电站名称: {station['stationName']}, ID: {station['stationId']}")
        else:
            print("\n未找到任何充电站信息")

    except Exception as e:
        print(f"程序执行出错: {str(e)}")


if __name__ == "__main__":
    main()

这里我们基于上海的一个原始定位点,获取周边一些充电桩位置信息,获取数据标签如下,stationId(充电桩id)、stationName(充电桩名称)、acNum(交流充电桩)、dcNum (直流充电桩)、distance(距离查询点距离)latitude,longitude(坐标信息)s4Num(S4超级充电桩)、showXpOwner(是否由小鹏汽车直接运营)、stationOperationStatus(站点运营状态),其他一些非关键标签,这里省略;

tips:1、我在脚本里增加了1~3秒的每次查询随机延时,防止频繁访问;2、如果需要调整原始坐标点的话,通过高德坐标拾取api进行拾取新的坐标,如果需要扩大查询范围的话,可以通过修改layers 的层数进行调整;

第三步: 坐标系转换,由于小鹏充电桩数据使用的是高德坐标系(GCJ-02),为了在ArcGIS上准确展示而不发生偏移,我们需要将充电桩的坐标从GCJ-02转换为WGS-84坐标系。我们可以利用coord-convert库中的gcj2wgs(lng, lat)函数,也可以用免费这个网站:批量转换工具:地图坐标系批量转换 - 免费在线工具 (latlongconverter.online)

对CSV文件中的充电桩坐标列进行转换。完成坐标转换后,再将数据导入ArcGIS进行可视化;

根据在长三角地区部分 我们获取到的充电桩分布图,我们可以观察到小鹏汽车在长三角地区 的充电网络布局呈现出一些显著特征。首先,在城市密集区 如上海及其周边地区,充电桩的分布尤为集中。上海市区内及郊区的主要交通节点上设有大量充电桩站点,确保了城市居民和通勤者的便捷使用。同样地,在苏州无锡等邻近城市,特别是在交通枢纽和商业中心区域,也布置了较多的充电桩,以满足当地日益增长的新能源汽车用户需求。

沿着重要的高速公路 ,如G42沪蓉高速G15沈海高速,可以发现多个充电桩站点的存在。这表明小鹏汽车不仅关注城市内部的充电需求,还致力于解决长途旅行中的充电问题。这些分布在高速公路沿线的充电桩,为驾驶者提供了连续而可靠的充电保障,增强了新能源汽车出行的便利性和可靠性。

此外,在重要的交通枢纽 ,如浦东国际机场虹桥火车站 等地方,也配置了充电桩设施。这不仅方便了旅客的出行,也为临时需要充电的用户提供了一个理想的解决方案。与此同时,商业中心陆家嘴南京西路等地的大型购物中心和商场附近,充电桩的数量也相对较多,既服务于购物人群,也体现了对都市生活节奏的关注。

值得注意的是,旅游景区 也是小鹏汽车充电桩部署的重点之一。例如,迪士尼乐园外滩 等著名景点周围均设有充电桩,确保游客能够享受愉快旅程的同时,也能轻松解决车辆充电的需求,尽管在郊区和乡村地区的充电桩数量不及城市密集区,但在靠近高速公路的关键节点上仍有一定分布,保证了偏远地区用户的充电需求。这种全面而细致的布局策略,显示了小鹏汽车致力于打造一个覆盖广泛、使用便捷的充电网络的决心。

文章仅用于分享个人学习成果与个人存档之用,分享知识,如有侵权,请联系作者进行删除。所有信息均基于作者的个人理解和经验,不代表任何官方立场或权威解读。

相关推荐
究极无敌暴龙战神X2 分钟前
哈希表 - 两个数组的交集(集合、数组) - JS
前端·javascript·散列表
前端御书房5 分钟前
基于 Trae 的超轻量级前端架构设计与性能优化实践
前端·性能优化
南部余额10 分钟前
playwright解决重复登录问题,通过pytest夹具自动读取storage_state用户状态信息
前端·爬虫·python·ui·pytest·pylawright
前端与小赵21 分钟前
webpack和vite之间的区别
前端·webpack·vite
zy01010124 分钟前
React受控表单绑定
前端·javascript·react.js·mvvm·双向数据绑定
百锦再25 分钟前
React编程的核心概念:数据流与观察者模式
前端·javascript·vue.js·观察者模式·react.js·前端框架·ecmascript
2401_8724878826 分钟前
网络安全之前端学习(css篇2)
前端·css·学习
SuperYing37 分钟前
前端候选人突围指南:让面试官主动追着要简历的五大特质(个人总结版)
前端·面试
快来卷java40 分钟前
深入剖析 JVM:从组成原理到调优实践
java·jvm·spring boot·spring cloud·数据挖掘·maven
前端双越老师40 分钟前
我的编程经验与认知
前端