讲师中心 微信公众号
AI工具推荐 视频效率加速

Python中通过API获取地理距离:请求限流与数据整合实践

冬磊小哥_9493

冬磊小哥_9493

发布时间:2025-08-11 19:28:41

|

546人浏览过

|

来源于php中文网

原创

Python中通过API获取地理距离:请求限流与数据整合实践

本教程详细讲解如何利用Python通过外部API计算地理位置间的驾驶距离,并重点介绍如何实现API请求的限流以遵守服务条款。文章涵盖了API调用函数的构建、基于上下文管理器的智能限流机制、鲁棒的错误处理方法,以及最终将所有数据(包括原始坐标和计算出的距离)整合到Pandas DataFrame中的完整流程,旨在帮助读者高效、稳定地处理大规模地理空间数据请求。

1. 构建地理距离计算API函数

在处理地理空间数据时,我们经常需要计算两点间的实际驾驶距离。这通常通过调用第三方地图服务的api来实现。以下是一个使用osrm(open source routing machine)公共api计算驾驶距离的python函数示例。osrm提供了一个开放且高性能的路由服务,非常适合此类任务。

import requests
import json
import pandas as pd
from contextlib import contextmanager
from time import sleep
import http.client # For HTTPStatus

def get_driving_distance(lat1, lon1, lat2, lon2):
    """
    通过OSRM API计算两点间的驾驶距离。

    参数:
    lat1 (float): 起点纬度
    lon1 (float): 起点经度
    lat2 (float): 终点纬度
    lon2 (float): 终点经度

    返回:
    float: 驾驶距离(英里),如果请求失败则返回None
    """
    try:
        # OSRM API的URL结构:/route/v1/car/{lon1},{lat1};{lon2},{lat2}
        url = f"http://router.project-osrm.org/route/v1/car/{lon1},{lat1};{lon2},{lat2}?overview=false"
        response = requests.get(url)

        # 检查HTTP响应状态码,如果不是2xx则抛出异常
        response.raise_for_status()

        data = json.loads(response.content)

        # 检查API响应中是否有路由信息
        if data.get("routes") and len(data["routes"]) > 0:
            driving_distance_meters = data["routes"][0]['distance']
            # 将米转换为英里 (1 英里 = 1609.34 米)
            driving_distance_miles = driving_distance_meters / 1609.34
            return driving_distance_miles
        else:
            print(f"API响应未包含有效路由信息: {data}")
            return None
    except requests.exceptions.RequestException as e:
        print(f"API请求失败: {e}")
        return None
    except json.JSONDecodeError as e:
        print(f"JSON解析失败: {e}")
        return None
    except KeyError as e:
        print(f"API响应结构异常,缺少键: {e}")
        return None

注意事项:

  • 坐标顺序: OSRM API通常要求经度在前,纬度在后(lon,lat)。请务必核对您的数据顺序。
  • overview=false: 这个参数可以减少API响应中路由几何信息的详细程度,从而减小响应体大小,提高效率。
  • 错误处理: response.raise_for_status() 是一个非常重要的错误处理机制。如果HTTP请求返回的状态码表示错误(例如4xx或5xx),它会自动抛出 requests.exceptions.HTTPError 异常,避免程序在处理无效响应时崩溃。

2. 实现API请求限流机制

当需要进行大量API调用时,为了避免对API服务器造成过大压力或触及API服务提供商的调用限制,实现请求限流(Rate Limiting)至关重要。我们可以利用Python的上下文管理器(contextlib.contextmanager)来优雅地实现这一功能。

# 定义一个全局变量来跟踪API调用次数
api_calls = 0

@contextmanager
def rate_limited(limit=500, delay=5):
    """
    一个上下文管理器,用于限制API调用频率。
    当API调用次数达到指定限制时,暂停指定时间。

    参数:
    limit (int): 在暂停前允许的最大API调用次数。
    delay (int): 暂停的秒数。
    """
    global api_calls
    # 检查是否即将超过限制
    if api_calls + 1 >= limit:
        print(f"达到 {limit} 次API调用限制,暂停 {delay} 秒...")
        sleep(delay)
        # 暂停后,重置计数器(或减去已处理的批次)
        api_calls = 0 # 简单重置,也可以 api_calls -= limit

    api_calls += 1
    yield # 执行被包装的代码
    # 上下文退出时,无需额外操作

# 更新 get_driving_distance 函数以集成限流
def get_driving_distance_with_rate_limit(lat1, lon1, lat2, lon2):
    """
    通过OSRM API计算两点间的驾驶距离,并集成请求限流。
    """
    with rate_limited(): # 在这里应用限流
        return get_driving_distance(lat1, lon1, lat2, lon2)

工作原理:

  • api_calls:一个全局计数器,记录当前批次的API调用次数。
  • rate_limited 上下文管理器:
    • 在进入 with 块之前,它会检查 api_calls 是否接近 limit。
    • 如果接近,则调用 time.sleep(delay) 暂停执行。
    • 暂停后,api_calls 被重置(或相应调整),以便新的批次可以开始计数。
    • api_calls 每次进入 with 块时都会递增。
    • yield 关键字使得被包装的代码(即 get_driving_distance 的内容)得以执行。
  • 通过将 get_driving_distance 函数包裹在 with rate_limited(): 语句中,每次调用该函数时都会自动触发限流逻辑。

3. 数据整合至Pandas DataFrame

最终目标是将原始的地理坐标数据与计算出的驾驶距离整合到一个结构化的Pandas DataFrame中,方便后续的数据分析和可视化。

立即学习“Python免费学习笔记(深入)”;

digital-solution-designer
digital-solution-designer

系统化设计数字化解决方案,涵盖方案类型识别、政策背景分析、需求分析、建设思路设计、架构设计(业务、功能、数据、技术四维度)、技术选型、具体建设内容、实施规划、风险评估和投资估算的全流程能力。适用于规划类、申报类、可研类、投标类和工作汇报类等多种方案产出场景,覆盖政府数字化转型和企业数字化转型两大核心领域。

下载

假设我们有四组列表数据:起点纬度、起点经度、终点纬度、终点经度。

# 示例数据
location_latitudes = [51.5074, 40.7128, 34.0522]
location_longitudes = [-0.1278, -74.0060, -118.2437]
station_latitudes = [51.5154, 40.7580, 34.0522]
station_longitudes = [-0.0920, -73.9855, -118.2437]

# 存储计算出的距离
driving_distances = []

# 遍历数据并计算距离
for i in range(len(location_latitudes)):
    lat1 = location_latitudes[i]
    lon1 = location_longitudes[i]
    lat2 = station_latitudes[i]
    lon2 = station_longitudes[i]

    distance = get_driving_distance_with_rate_limit(lat1, lon1, lat2, lon2)
    driving_distances.append(distance)

    # 打印进度(可选)
    print(f"处理第 {i+1} 对坐标: ({lat1},{lon1}) -> ({lat2},{lon2}), 距离: {distance:.2f} 英里")

# 创建DataFrame
data = {
    'Location_Lat': location_latitudes,
    'Location_Lon': location_longitudes,
    'Station_Lat': station_latitudes,
    'Station_Lon': station_longitudes,
    'Driving_Distance_Miles': driving_distances
}

df = pd.DataFrame(data)

print("\n最终生成的DataFrame:")
print(df)

代码说明:

  1. 准备数据: 示例中创建了四个列表,分别代表起点和终点的经纬度。在实际应用中,这些数据可能来自CSV文件、数据库或其它数据源。
  2. 迭代计算: 通过循环遍历这些列表,对每一对坐标调用 get_driving_distance_with_rate_limit 函数,并将返回的距离存储在 driving_distances 列表中。
  3. 构建DataFrame: 使用一个字典来组织所有相关数据(原始坐标和计算出的距离),然后将其传递给 pd.DataFrame() 构造函数,即可生成一个结构化的DataFrame。

4. 总结与最佳实践

本教程展示了如何结合Python的 requests 库、上下文管理器以及Pandas库,高效且稳定地处理地理距离计算任务。以下是一些额外的最佳实践和考虑事项:

  • 更健壮的错误处理: 对于生产环境应用,除了 raise_for_status() 外,还可以考虑实现重试机制(例如使用 tenacity 库),尤其是在面对临时性网络问题或API服务波动时。
  • 持久化数据: 对于大量API调用,建议将中间结果定期保存到文件(如CSV、JSON),以防程序中断或网络问题导致数据丢失,避免重复昂贵的API请求。
  • API密钥管理: 如果您使用的是需要API密钥的商业地图服务(如Google Maps API),请务必妥善管理您的密钥,不要将其硬编码在代码中。可以使用环境变量或配置文件来存储。
  • 异步请求: 对于极其庞大的数据集,可以考虑使用异步请求库(如 aiohttp)来并发地发送API请求,进一步提高效率,但这会增加代码的复杂性。
  • 遵守API服务条款: 始终阅读并遵守您所使用的API服务提供商的条款和条件,包括请求限制、使用范围等。不当使用可能导致IP被封禁或账户被禁用。
  • 选择合适的API: OSRM是一个优秀的开源选择,但对于需要更高级功能(如交通信息、路线优化、地理编码等)或更高请求限制的场景,可能需要考虑商业API服务。

通过遵循这些指导原则,您可以构建出稳定、高效且符合规范的地理空间数据处理应用程序。

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2255

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3642

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1216

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

4219

2025.09.10

Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

340

2025.12.04

Python 数据清洗与预处理实战
Python 数据清洗与预处理实战

本专题系统讲解 Python 在数据清洗与预处理中的核心技术,包括使用 Pandas 进行缺失值处理、异常值检测、数据格式化、特征工程与数据转换,结合 NumPy 高效处理大规模数据。通过实战案例,帮助学习者掌握 如何处理混乱、不完整数据,为后续数据分析与机器学习模型训练打下坚实基础。

272

2026.01.31

Python数据分析与Pandas高级实战
Python数据分析与Pandas高级实战

本专题围绕 Python 数据分析展开,系统讲解 Pandas 的高级用法,包括数据清洗、透视表、时间序列分析以及多表合并与分组操作。通过实战案例,帮助开发者掌握高效处理与分析数据的方法,提高数据处理效率与分析能力。

811

2026.04.13

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

3045

2023.06.29

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

0

2026.11.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn