您现在的位置是:首页 >学无止境 >ChatGPT工作提效之使用python开发对接百度地图开放平台API的实战方案(批量路线规划、批量获取POI、突破数量有限制、批量地理编码)网站首页学无止境

ChatGPT工作提效之使用python开发对接百度地图开放平台API的实战方案(批量路线规划、批量获取POI、突破数量有限制、批量地理编码)

漏刻有时 2024-06-28 00:01:02
简介ChatGPT工作提效之使用python开发对接百度地图开放平台API的实战方案(批量路线规划、批量获取POI、突破数量有限制、批量地理编码)

ChatGPT工作提效系列文章目录

ChatGPT工作提效系列

  1. ChatGPT工作提效之初探路径独孤九剑遇强则强
  2. ChatGPT工作提效之在程序开发中的巧劲和指令(创建MySQL语句、PHP语句、Javascript用法、python的交互)
  3. ChatGPT工作提效之生成开发需求和报价单并转为Excel格式
  4. ChatGPT工作提效之小鹅通二次开发批量API对接解决方案(学习记录同步、用户注册同步、权益订购同步、开发文档)


前言

一般来说,利用 Python 对接百度地图开放平台 API 主要有以下几种方式:

  1. 直接通过 requests 请求发送 HTTP 请求,获取响应结果。

这种方式比较简单直接,可以通过 requests 库发送 GET、POST 等不同类型的请求,获取响应结果后进行解析和处理。示例代码:

import requests

# 百度地图 API 地址
url = "https://api.map.baidu.com/place/v2/search"

# 请求参数
params = {
    "query": "酒店",
    "region": "北京",
    "output": "json",
    "ak": "你的百度地图开发者密钥"
}

# 发送请求
response = requests.get(url, params=params)

# 处理响应结果
if response.status_code == 200:
    json_data = response.json()
    # 进行数据解析和处理
else:
    print("请求失败,状态码为", response.status_code)
  1. 使用百度地图 Python SDK 进行操作。

百度提供了 Python SDK 接口,可以方便地实现地理编码、路线规划、地图可视化等功能。SDK 中提供了丰富的 API 接口,也支持上传数据到百度云存储等操作。使用 SDK,需要先安装并导入百度地图的 Python SDK 包,示例代码:

from baidumap.api import PlaceSearch

ak = "你的百度地图开发者密钥"

params = {
    "query": "酒店",
    "region": "北京",
    "output": "json"
}

search = PlaceSearch(ak=ak)
res = search.place_search(**params)

if res.status == 0:
    print(res.results)
else:
    print("请求失败,状态码为", res.status)
  1. 使用百度地图开放平台提供的其他开发接口实现。

百度地图开放平台提供了多个开发接口,比如 JavaScript API、Web API、移动端 API 等等,选择适合自己场景的 API 接口可以更加方便地实现自己的应用和功能。每个接口都会提供详细的 API 文档和示例,根据需求选择合适的 API 接口进行开发即可。

那么如何利用ChatGPT来提效呢?


一、批量经纬度坐标路线规划

百度地图路线规划什么意思

百度地图路线规划,是指根据起始地点和终止地点,使用百度地图提供的驾车、步行或公交等不同出行方式,计算出最优路径和行驶时间等信息的过程。具体来说,百度地图路线规划通常包含以下几个步骤:

  1. 解析起始地点和终止地点的坐标:用户输入的起始地点和终止地点一般是以地址的形式呈现,需要通过地理编码的技术将其转换为经纬度坐标。

  2. 根据不同出行方式选择最优路径:根据用户选择的出行方式(驾车、步行、公交等),通过算法和实时交通情况,选择并规划出一条最优路径。其中,驾车路径规划还包括交通限制、高速费用、实时路况等因素的考虑。

  3. 计算行驶距离和时间:在规划出最优路径后,通过计算路径距离和行驶时间等指标,提供给用户参考。

  4. 显示路径和导航:将规划的路径展示到地图上,标注主要路线和途经的关键点,并提供导航和语音提示等辅助功能。

通过百度地图路线规划,可帮助人们更好地了解出行路线、行驶距离、行驶时间等相关信息,方便出行安排和交通规划。

如何批量实现起始点路线规划,进行计算距离和耗时,封装成一个函数,并导出excle表格。

以下是一个将起始点路线规划计算封装成函数,并批量计算距离和耗时,并导出 Excel 表格的 Python 代码示例:

首先,安装必要的依赖:

pip install requests openpyxl

然后,导入需要的模块:

import requests
import openpyxl
from openpyxl.utils import get_column_letter
from openpyxl.styles import Alignment

最后,定义封装函数并调用:

def calculate_distance_duration(api_key, origins, destinations, excel_file_path):
    """
    计算起始点路线规划的距离和耗时,并保存到 Excel 表格中
    :param api_key: 百度地图开发者密钥
    :param origins: 起点坐标列表,每个元素为一个字符串,如 ['116.43213,39.99858', '116.118904, 24.46807']
    :param destinations: 终点坐标列表,每个元素为一个字符串
    :param excel_file_path: Excel 文件路径
    :return: 返回导出的 Excel 表格路径
    """
    # 定义 API 路径和请求参数
    api_url = 'http://api.map.baidu.com/direction/v2/driving'
    api_params = {
        'ak': api_key,
    }

    # 创建 Excel 工作簿和工作表
    wb = openpyxl.Workbook()
    ws = wb.active

    # 创建表头
    ws['A1'] = '起始点'
    ws['B1'] = '终点'
    ws['C1'] = '距离(米)'
    ws['D1'] = '耗时(分钟)'

    # 格式化表头
    for cell in ws[1]:
        cell.font = openpyxl.styles.Font(bold=True)
        cell.alignment = Alignment(horizontal='center', vertical='center')

    # 遍历起始点和终点坐标列表,计算路线规划
    for i, origin in enumerate(origins, start=2):
        for j, destination in enumerate(destinations, start=2):
            # 构造请求参数
            api_params.update({
                'origin': origin,
                'destination': destination,
            })

            # 发送请求
            response = requests.get(api_url, params=api_params)
            if response.status_code == 200:
                # 解析响应
                json_data = response.json()
                routes = json_data['result']['routes']
                if routes:
                    # 获取最短路线方案
                    route = min(routes, key=lambda x: x['distance'])

                    # 提取距离和时间
                    distance = route['distance']
                    duration = route['duration'] // 60

                    # 将结果保存到 Excel 表格中
                    row = [origin, destination, distance, duration]
                    for k, value in enumerate(row, start=1):
                        cell = ws.cell(row=i, column=k, value=value)
                        cell.alignment = Alignment(horizontal='center', vertical='center')
                else:
                    print(f'未找到起点 {origin} 和终点 {destination} 之间的路线规划')
            else:
                print(f'获取起点 {origin} 和终点 {destination} 的路线规划失败,状态码:{response.status_code}')

    # 自适应列宽
    for column in ws.columns:
        column_letter = get_column_letter(column[0].column)
        ws.column_dimensions[column_letter].width = max(len(str(cell.value)) for cell in column)

    # 保存 Excel 文件,并返回文件路径
    wb.save(excel_file_path)

    return excel_file_path

使用示例:

# 测试数据
my_api_key = 'your_api_key'
start_locations = ['116.43213,39.99858', '116.118904, 24.46807']
end_locations = ['116.43187,39.99765', '117.2428, 31.8427']

# 计算起始点路线规划的距离和耗时,并保存到 Excel 表格中
calculate_distance_duration(my_api_key, start_locations, end_locations, '计算距离.xlsx')

其中,参数 api_key 为你的百度地图开发者密钥,`origins

二、批量爬取某城市指定类目POI

使用python如何批量爬取某城市指定类目POI,如杭州市拱墅区美食的兴趣点,并导出excel表格,具体代码怎么写

1.爬取POI 数量有限制

以下是使用 Python 爬取某城市指定类目 POI(例如杭州市拱墅区美食)并导出 Excel 表格的代码示例:

import requests
import openpyxl

# 输入百度地图开发者密钥
MY_API_KEY = 'your_api_key'

# 定义 API 路径
url = 'http://api.map.baidu.com/place/v2/search'

# 起点坐标和查询类别
query = '美食'
region = '杭州市拱墅区'
page_size = 20  # 每页数据量,最大为 20
page_num = 0  # 起始页码

# 创建 Excel 工作簿和工作表
wb = openpyxl.Workbook()
ws = wb.active
ws['A1'] = '名称'
ws['B1'] = '经度'
ws['C1'] = '纬度'
ws['D1'] = '地址'

# 循环爬取每一页的数据
while True:
    # 构建请求参数
    payload = {
        'query': query,
        'region': region,
        'ak': MY_API_KEY,
        'output': 'json',
        'page_size': page_size,
        'page_num': page_num,
    }

    # 发送请求
    response = requests.get(url, params=payload)
    if response.status_code != 200:
        print('请求错误', response.status_code)
        break

    # 解析响应
    json_data = response.json()
    if json_data.get('status') != 0:
        print(f"获取 {region} {query} 数据失败: {json_data.get('message')}")
        break

    # 获取总记录数和当前页码的数据
    total = json_data.get('total')
    results = json_data.get('results')

    # 将当前页码的数据写入 Excel 表格
    for i, result in enumerate(results, start=2 + page_num * page_size):
        name = result.get('name')
        location = result.get('location')
        address = result.get('address')
        ws.cell(row=i, column=1, value=name or '')
        ws.cell(row=i, column=2, value=location.get('lng', '') or '')
        ws.cell(row=i, column=3, value=location.get('lat', '') or '')
        ws.cell(row=i, column=4, value=address or '')

    # 如果已经获取了总记录数,则跳出循环
    if total:
        if page_num * page_size + len(results) >= total:
            break

    # 自增页码
    page_num += 1

# 自适应列宽
for column in ws.columns:
    cell = max(column, key=lambda x: len(str(x.value)))
    width = min(100, max(10, len(str(cell.value))))
    ws.column_dimensions[cell.column_letter].width = width

# 保存 Excel 文件
wb.save(f"{region}{query}.xlsx")

需要注意以下几点:

  1. 首先,需要在百度地图开放平台上注册并获取自己的开发者密钥 MY_API_KEY。
  2. 请求路径参数 url 中的 /place/v2/search 表示的是 POI 搜索,如果要获取其他类型的信息,需要更改请求路径,具体可以参考官方文档。
  3. 请求参数 payload 中的 queryregion 分别表示查询类别和查询地点,在实际使用中,可以根据自己的需求进行更改,如 美食 可以改成 酒店 或其他类别,杭州市拱墅区 可以改成 浙江省杭州市 或其他地点。
  4. 更改请求参数中的 page_size 可以控制每页数据量,最大值为 20。
  5. 结果会在工作簿第一个活动工作表中创建,包含 POI 的名称、经度、纬度和地址信息。
  6. 自适应列宽代码可以让每一列的宽度自适应单元格内容的长度。
  • 生成的POI地址,因百度地图接口的显示,数量不多;

在这里插入图片描述

2.突破POI 数量有限制

百度地图 API 请求返回的 POI 数量有限制,即每个开发者密钥每天只能调用一定次数的 API 接口,并且每个查询请求也有最大结果数、页码等限制。如果需要尽可能获取更多的 POI,可以参考以下几点:

  1. 在多个城市或区域中查询,可以通过 region 参数传递多个城市或区域的信息,例如 '杭州市拱墅区|杭州市西湖区|杭州市余杭区'
  2. 增加查询关键词的精度或缩小查询范围,例如可以使用 '火锅|串串香|川菜' 替代 '美食'
  3. 对于一个城市或一个区域,可以通过循环调用多个页面的方式来获取更多的结果,例如设置 page_num 的初始值不为 0,并不断自增 page_num 直至达到最大页码数或者超过总的记录数。例如,可以设置 max_page_num = 20 或其他自定义值,最大也不得超过 ceil(total / page_size)

下面是修改过后的代码示例:

import math

import requests
import openpyxl


# 输入百度地图开发者密钥
MY_API_KEY = 'your_api_key'

# 定义 API 路径
url = 'http://api.map.baidu.com/place/v2/search'

# 起点坐标和查询类别
query = '火锅|串串香|川菜'
region = '杭州市拱墅区'
page_size = 20  # 每页数据量,最大为 20
page_num = 0  # 起始页码
max_page_num = 100  # 最大页码数,最大不得超过 ceil(total / page_size)

# 创建 Excel 工作簿和工作表
wb = openpyxl.Workbook()
ws = wb.active
ws['A1'] = '名称'
ws['B1'] = '经度'
ws['C1'] = '纬度'
ws['D1'] = '地址'

# 获取总记录数
total = None

while not total or page_num * page_size < total:
    # 构建请求参数
    payload = {
        'query': query,
        'region': region,
        'ak': MY_API_KEY,
        'output': 'json',
        'page_size': page_size,
        'page_num': page_num,
    }

    # 发送请求
    response = requests.get(url, params=payload)
    if response.status_code != 200:
        print('请求错误', response.status_code)
        break

    # 解析响应
    json_data = response.json()
    if json_data.get('status') != 0:
        print(f"获取 {region} {query} 数据失败: {json_data.get('message')}")
        break

    # 获取总记录数
    if total is None:
        total = json_data.get('total')

    # 获取当前页码的数据
    results = json_data.get('results')

    # 将当前页码的数据写入 Excel 表格
    for i, result in enumerate(results, start=2 + page_num * page_size):
        name = result.get('name')
        location = result.get('location')
        address = result.get('address')
        ws.cell(row=i, column=1, value=name or '')
        ws.cell(row=i, column=2, value=location.get('lng', '') or '')
        ws.cell(row=i, column=3, value=location.get('lat', '') or '')
        ws.cell(row=i, column=4, value=address or '')

    # 自增页码
    page_num += 1

    # 如果已经获取了总记录数,则控制最大页码数
    if total is not None:
        max_page_num = min(math.ceil(total / page_size), max_page_num)

    # 如果达到最大页码数,则跳出
    if page_num >= max_page_num:
        break

# 自适应列宽
for column in ws.columns:
    cell = max(column, key=lambda x: len(str(x.value)))
    width = min(100, max(10, len(str(cell.value))))
    ws.column_dimensions[cell.column_letter].width = width

# 保存 Excel 文件
wb.save(f"{region}{query}.xlsx")

需要注意以下几点:

  • 在获取查询结果总记录数时,只需要获取一次即可,可以通过判断 total 是否为 None 来控制。获取到 total 后,可以计算出最大页码数,确保不会超过 ceil(total / page_size)
  • 循环爬取每一页的数据时,可以通过 page_num * page_size < total 的判断条件来控制循环次数,并在到达最大页码数后及时跳出循环,避免超调用 API 接口次数。
  • 增加查询词和查询地点的精度或范围可以控制返回结果数量。查询结果数量过大时,需要对数据进行去重、排序、过滤等处理,以避免数据冗余和格式不统一的问题。

3.百度地图API升级与ChatGPT的旧代码冲突

在调试的过程中,由于近期百度地图的升级,ChatGPT生成的代码还是老的版本,无法直接运行。需要我们重新梳理,借鉴ChatGPT的算法。

  • 构建请求参数的变化
    # 构建请求参数
    payload = {
        'query': '酒店',
        "tag": "商务酒店,招待所,星级酒店",
        'region': '浙江省杭州市拱墅区',
        'ak': MY_API_KEY,
        'output': 'json',
        'page_size': 20,
        'page_num': 0,
    }

在这里插入图片描述

  • ‘APP 服务被禁用’

{‘status’: 240, ‘message’: ‘APP 服务被禁用’}的解决方案:替换成服务端的ak,也是近期的百度地图升级。
在这里插入图片描述

  • origin or destination is invalid,起始点无效。

{‘status’: 2, ‘message’: ‘origin or destination is invalid’}的解决方案:API路径和请求参数的升级,参照官网比对。

在这里插入图片描述


三、获取当前城市的天气情况

使用百度地图开放平台,获取当前城市的天气情况,代码怎么写

以下是使用百度地图开放平台,获取当前城市天气情况的 Python 代码示例:

import requests

# 输入百度地图开发者密钥
MY_API_KEY = 'your_api_key'

# 获取当前 IP 和城市信息
ip_api_url = 'http://api.map.baidu.com/location/ip'
payload = {
    'ak': MY_API_KEY,
    'ip': '',
    'coor': 'bd09ll',
}
response = requests.get(ip_api_url, params=payload)
if response.status_code != 200:
    print('请求错误', response.status_code)
    raise SystemExit(0)
json_data = response.json()
if json_data.get('status') != 0:
    print(f"获取 IP 地址数据失败: {json_data.get('message')}")
    raise SystemExit(0)
city_name = json_data['address_detail']['city']

# 获取城市天气数据
weather_api_url = 'http://api.map.baidu.com/weather/v1'
payload = {
    'district_id': '',
    'output': 'json',
    'ak': MY_API_KEY,
}
response = requests.get(weather_api_url, params=payload)
if response.status_code != 200:
    print('请求错误', response.status_code)
    raise SystemExit(0)
json_data = response.json()
if json_data.get('status') != 0:
    print(f"获取天气数据失败: {json_data.get('message')}")
    raise SystemExit(0)

# 解析天气数据
weather_data = {}
for city in json_data['result']:
    if city_name in (city.get('name', ''), city.get('alias', '')):
        weather_data = {
            '城市': city_name,
            '天气': city['weather_data'][0]['wea'],
            '温度': city['weather_data'][0]['tem'],
            '风向': city['weather_data'][0]['win'],
            '湿度': city['weather_data'][0]['humidity'],
            '空气质量': city['air'],
            '更新时间': city['update_time'],
        }
        break

# 输出天气数据
if weather_data:
    print(f"城市: {weather_data['城市']}")
    print(f"天气: {weather_data['天气']}")
    print(f"温度: {weather_data['温度']}")
    print(f"风向: {weather_data['风向']}")
    print(f"湿度: {weather_data['湿度']}")
    print(f"空气质量: {weather_data['空气质量']}")
    print(f"更新时间: {weather_data['更新时间']}")
else:
    print(f"当前城市:{city_name} 无天气数据")

需要注意以下几点:

  1. 首先需要在百度开放平台上注册并获取密钥 MY_API_KEY
  2. 获取当前 IP 和城市信息,可以通过发送请求访问百度地图开放 API 的 location/ip 接口,然后解析返回的 JSON 数据来获取 IP 地址和城市信息。
  3. 获取城市天气数据,可以通过发送请求访问百度地图开放 API 的 weather/v1 接口,然后将查询结果中包含当前城市天气数据的条目提取出来。
  4. 天气结果中包含城市、天气、温度、风向、湿度、空气质量和更新时间等信息,可以针对不同的信息进行处理、显示或统计。

在这里插入图片描述

如何解决获取 IP 地址数据失败: Unkown Error:no ipv6 permission, please apply through feedback

百度地图开放平台的 location/ip 接口是需要用户的设备支持 IPv6 协议才能正常使用的,否则会出现 Unkown Error:no ipv6 permission, please apply through feedback 的错误提示。

为了解决此问题,可以参考以下两种方法:

  1. 在设备上开启 IPv6 协议支持。具体的开启方式和步骤会因设备和系统版本而不同,可以在设备设置中进行查找和开启。
  2. 向百度地图开放平台反馈问题。如果设备无法支持 IPv6 协议,则可以向百度地图开放平台反馈该问题,请求其增加对 IPv4 协议的支持。具体的操作流程可以参考百度地图开放平台的官方文档。

四、批量地理编码

如何使用百度地图web API,对地址批量进行转换为经纬度坐标,并输出excel
在这里插入图片描述

可以使用百度地图 web API 的 Geocoding API 接口实现将批量地址转换为经纬度坐标,并将结果输出到 Excel 文件中。以下是 Python 代码示例:

import requests
import openpyxl

# 输入百度地图开发者密钥和读取的地址列表(每个地址占据列表中一行)
MY_API_KEY = 'your_api_key'
addr_list = ['浙江省杭州市西湖区浙江大学紫金港校区1号楼', '浙江省杭州市西湖区浙江大学紫金港校区2号楼']

# 定义 API 路径和 Excel 文件名
url = 'http://api.map.baidu.com/geocoding/v3/'
excel_file = '地址坐标.xlsx'

# 创建 Excel 工作簿和工作表
wb = openpyxl.Workbook()
ws = wb.active
ws['A1'] = '地址'
ws['B1'] = '经度'
ws['C1'] = '纬度'

# 循环获取地址坐标并写入 Excel 表格
for i, addr in enumerate(addr_list, start=2):
    payload = {'address': addr, 'output': 'json', 'ak': MY_API_KEY}
    response = requests.get(url, params=payload)
    if response.status_code != 200:
        print('请求错误', response.status_code)
        break
    json_data = response.json()
    if json_data.get('status') != 0:
        print(f"获取坐标数据失败: {json_data.get('message')}")
        break
    location = json_data['result']['location']
    ws.cell(row=i, column=1, value=addr or '')
    ws.cell(row=i, column=2, value=location.get('lng', '') or '')
    ws.cell(row=i, column=3, value=location.get('lat', '') or '')

# 自适应列宽
for column in ws.columns:
    cell = max(column, key=lambda x: len(str(x.value)))
    width = min(100, max(10, len(str(cell.value))))
    ws.column_dimensions[cell.column_letter].width = width

# 保存 Excel 文件
wb.save(excel_file)
print(f"文件{excel_file}保存成功")

需要注意以下几点:

  1. 首先需要在百度开放平台上注册并获取密钥 MY_API_KEY
  2. 将需要查询的地址存储在以地址为元素的列表 addr_list 中,每个地址占据列表中的一行。
  3. 使用 requests 库向百度地图 web API 的 Geocoding API 接口发送查询请求,查询参数为地址和密钥。返回的 JSON 数据中包含地址的经纬度坐标信息。
  4. 将查询结果写入一个新的 Excel 工作簿,并设置工作表的列宽自适应。

总结

ChatGPT是在不断学习和成长中的AI,对于及时更新的信息还达不到实时更新,尤其是对于一些商用平台开放平台API接口,需要技术开发者,在官方文档为主的情况下,借助ChatGPT进行快速有效的技术开发。

@漏刻有时

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。