Python实战:用高德地图API批量获取地址所属街道并写回Excel

作者:程序员爱钓鱼日期:2025/11/8

在日常的数据处理工作中,我们经常需要根据公司、事件或门店的注册地址,批量获取其所在的街道信息,例如“浦东新区张江镇”“徐汇区龙华街道”等。 手动查询显然低效,而借助 Python + 高德地图API,我们可以轻松实现自动化批量查询并将结果写入 Excel 文件中。

本文将完整展示一个从 Excel 读取地址 → 调用高德API → 获取街道 → 写回Excel的实用脚本,并讲解实现细节与优化思路。


一、功能概述

这段脚本的功能可以总结为四步:

  1. 从 Excel 文件中读取地址数据;
  2. 调用高德地图地理编码(geocode)与逆地理编码(regeo)接口获取街道名称;
  3. 自动将查询结果写回到 Excel 的新列中;
  4. 对查询失败的地址进行重试与记录,保证数据尽量完整。

二、项目依赖与准备工作

在开始之前,请确保安装以下依赖:

1pip install pandas openpyxl requests
2

并在高德开放平台申请一个 API Key,申请地址为: 👉 lbs.amap.com/api/webserv…

拿到 key 后,将它填入脚本开头的配置部分:

1key = "你的高德API_KEY"
2

三、核心逻辑讲解

1. Excel文件读取与列处理

脚本使用 pandasopenpyxl 结合读取 Excel 文件:

1df = pd.read_excel(input_file)
2if '注册地址' not in df.columns:
3    df['注册地址'] = df.iloc[:,16]
4addresses = df['注册地址'].tolist()
5

这段代码首先读取整个 Excel,然后确认是否存在“注册地址”列; 如果没有,则自动取第 17 列(索引16)作为地址列,保证兼容不同格式的表格。

随后,脚本用 openpyxl 打开同一个文件,以保留单元格样式,准备写入新的“街道”列:

1wb = load_workbook(input_file)
2ws = wb.active
3ws.insert_cols(target_col)
4ws.cell(row=header_row_index, column=target_col, value="街道")
5

这样既能读取数据,又能保持表格原有格式,方便下游人员直接查看。


2. 调用高德API获取街道信息

核心的查询函数如下:

1def get_street_from_amap(address, retries=max_retries):
2    if not isinstance(address, str) or not address.strip():
3        return ""
4    for attempt in range(1, retries+1):
5        try:
6            geo_resp = requests.get(
7                "https://restapi.amap.com/v3/geocode/geo",
8                params={"key": key, "address": address, "city": "上海"},
9                timeout=15
10            ).json()
11
12            if not geo_resp.get("geocodes"):
13                continue
14
15            location = geo_resp["geocodes"][0]["location"]
16
17            regeo_resp = requests.get(
18                "https://restapi.amap.com/v3/geocode/regeo",
19                params={"key": key, "location": location, "extensions": "base", "radius":500},
20                timeout=15
21            ).json()
22
23            if regeo_resp.get("regeocode"):
24                township = regeo_resp["regeocode"]["addressComponent"].get("township","") or ""
25                return township
26        except Exception as e:
27            print(f"[尝试 {attempt}/{retries}] 地址查询失败: {address}, 错误: {e}")
28        time.sleep(sleep_time + random.random()*0.5)
29    return None
30

这段逻辑分为两步:

  1. 正向地理编码(geocode):根据地址字符串获取经纬度;
  2. 逆向地理编码(regeo):根据经纬度反查街道名称(township)。

并加入了异常重试机制随机延时,防止频繁请求触发高德API限流。


3. 批量查询与缓存优化

查询过程通过循环实现:

1cache = {}
2failed_addresses = []
3
4for row_idx, addr in enumerate(addresses, start=header_row_index+1):
5    if not isinstance(addr,str) or not addr.strip():
6        ws.cell(row=row_idx, column=target_col, value="")
7        continue
8    if addr in cache:
9        township = cache[addr]
10    else:
11        township = get_street_from_amap(addr)
12        if township is None:
13            failed_addresses.append((row_idx, addr))
14            township = ""
15        cache[addr] = township
16        time.sleep(sleep_time + random.random()*0.5)
17    ws.cell(row=row_idx, column=target_col, value=township)
18

这里有几个优化点:

  • 缓存(cache)机制:如果同一地址出现多次,只请求一次;
  • 延时策略sleep_time + random.random()*0.5,避免被API风控;
  • 实时进度输出:每50行打印一次进度。

4. 失败重试与错误记录

对于第一次查询失败的地址,脚本会自动发起第二轮重查:

1if failed_addresses:
2    print(f"第一次查询失败地址共 {len(failed_addresses)} 条,开始自动重查……")
3    still_failed = []
4    for row_idx, addr in failed_addresses:
5        township = get_street_from_amap(addr)
6        if township is None:
7            still_failed.append((row_idx, addr))
8            township = ""
9        cache[addr] = township
10        ws.cell(row=row_idx, column=target_col, value=township)
11        time.sleep(sleep_time + random.random()*0.5)
12    failed_addresses = still_failed
13

最终仍查询失败的地址会被写入单独的 Excel 文件:

1if failed_addresses:
2    df_fail = pd.DataFrame([addr for _, addr in failed_addresses], columns=["地址"])
3    df_fail.to_excel(failed_file, index=False)
4

这样可以方便人工二次处理,比如手动调整地址格式或补录缺失信息。


四、运行结果

执行脚本后,控制台会显示类似输出:

1已处理 50 行,最近地址:上海市浦东新区张江路123号 → 张江镇
2已处理 100 行,最近地址:上海市浦东新区川沙路56号 → 川沙新镇
3第一次查询失败地址共 5 条,开始自动重查……
4完成,已保存:事件列表-上海浦东-带街道.xlsx
5最终仍失败的地址已保存到 查询失败地址.xlsx
6

最终输出文件中会新增一列“街道”,完整保留原有格式:

注册地址街道
上海市浦东新区张江路123号张江镇
上海市浦东新区川沙路56号川沙新镇

五、实用建议与扩展方向

  1. 批量查询速度控制
    • 高德API对单IP有请求频率限制,建议控制每秒请求数。
    • 若数据量大,可考虑多线程+限速队列模式。
  2. 地址清洗预处理
    • 可先对地址进行正则清洗,去掉多余标点、括号、空格等,提高命中率。
  3. 多城市适配
    • 当前城市固定为“上海”,可通过参数配置实现全国适配。
  4. 异常日志记录
    • 建议在重查阶段输出更多日志,例如返回状态码、错误类型,方便调试。
  5. 接口替代方案
    • 若数据量巨大,可以使用高德地图的批量地理编码接口(支持最多 10 条一次),进一步提升效率。

六、总结

本文通过一个实战案例展示了如何用 Python + 高德地图API 实现“批量地址→街道归属”的自动化处理。 整个过程涵盖了数据读取、接口调用、异常重试、结果写回等完整流程,既是一个实用工具脚本,也体现了 Python 在数据自动化中的强大能力。

核心亮点:

模块功能
pandas + openpyxl高效读取与写入 Excel
requests调用高德API进行地理解析
缓存与重试机制提高查询稳定性与速度
自动生成失败文件方便人工补录与质量控制

如果你日常需要处理大量企业、门店、事件地址,这个脚本可以帮你节省大量时间。



Python实战:用高德地图API批量获取地址所属街道并写回Excel》 是转载文章,点击查看原文


相关推荐


HTML中JS监听输入框值的即时变化
雨过天晴而后无语2025/11/5

一、说明         上一篇文章中提到了需要监听页面的一些组件内容变化,以便于更好的判断页面是否有更改,而控制“确定”按钮。         本里以JS监听输入框值的即时变化为引子,对这样的需求进行一个示例。 二、示例代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmln


pdf文件上传下载记录
家有两宝,感恩遇见2025/10/31

一:上传单个pdf文件并用hash重命名及判断文件是不是已经上传过,可以参考hash图片 @PostMapping("/uploadPdfFileSingle")     public String uploadPdfFileSingle(@RequestPart("file") MultipartFile file) {         System.err.println("开始文件上传");         if (file.isEmpty()) {             System


Redis(91)Redis的访问控制列表(ACL)是如何工作的?
Victor3562025/10/29

Redis 6.0及以上版本支持访问控制列表(ACL),这允许更细粒度地控制不同用户的权限。ACL使得可以定义多个用户,每个用户有自己的一组权限,这些权限可以控制哪些命令可以执行,哪些键可以访问等。以下是Redis ACL的详细工作原理和示例代码。 1. 基本概念 用户:Redis的每一个用户都有一个唯一的名字。 权限:每个用户可以被授予一组权限,这些权限定义了用户可以执行哪些命令和访问哪些键。 认证:用户在连接Redis时需要提供用户名和密码进行认证。 2. 配置ACL 可以在Redis配


Java Stream流两大实战陷阱:并行流Parallel误用、List转Map时重复键异常
IT橘子皮2025/10/26

在Java 8引入的Stream API极大地简化了集合操作,让函数式编程在Java世界中大放异彩。然而,在实践中发现的,Stream API并非银弹,其中隐藏着一些容易踩坑的陷阱。本文将深入分析Stream流中最常见的两大问题:并行流的误用和List转Map时的重复键异常,并提供相应的解决方案。 一、并行流(parallel)的陷阱与优化方案 1.1 问题本质分析 并行流看似是性能优化的"神器",但实践表明,盲目使用parallel()可能适得其反: // 看似高效的并行处理,实则是性能陷阱


C 语言标准库头文件 locale.h
hubenchang05152025/10/23

#C 语言标准库头文件 locale.h 请查看 C 语言标准库头文件列表 了解更多相关 API。 这个头文件提供 本地化 的相关功能,例如设置数字和货币的格式。 设置语言环境需要操作系统支持,通常需要安装语言包。 例如: sudo apt install language-pack-zh-hans # 安装中文语言包 #类型 类型标准说明lconvC89格式化详细信息 #宏 宏标准说明NULLC89空指针常量 本地化类别宏标准说明LC_ALLC89整个 C 语言环境LC_COLLATE


火狐浏览器替换js脚本
绘梨衣の沉默2025/10/22

一、概述 本教程使用火狐浏览器演示替换前端js脚本的操作步骤。 为了方便演示,教程中使用此页面作为案例进行讲解: https://www.leavescn.com/files/demos/1-snow/snow.html 这是一个使用js代码实现的展示下雪特效的页面,如下图所示: 本教程主要演示js代码的替换过程,对于功能复杂的网站,前端包含诸多js文件,需要具备一定的js基础,能够读懂源码后才能找到你需要替换的那个js文件。 二、步骤 使用火狐浏览器打开此网页,然后按下F12键打


Redis(75)Redis分布式锁的性能如何优化?
Victor3562025/10/21

优化Redis分布式锁的性能可以从多个方面入手,包括减少锁的粒度、使用Lua脚本来确保原子操作、优化网络通信、提高Redis服务器的性能,以及优化锁的实现逻辑等。以下是一些常见的性能优化方法,并结合代码进行详细解释。 1. 减少锁的粒度 锁的粒度越小,竞争的机会就越少,从而提高系统的并发性能。比如,将全局锁拆分为多个局部锁。 // 假设我们有多个资源需要加锁,可以为每个资源设置不同的锁 public class FineGrainedRedisLock { private Jedis j


为什么 .gitignore 不生效?其实你忘了用 git rm --cached!
唐青枫2025/10/20

简介 命令格式: git rm --cached <file> 意思: 从 Git 的 索引(index,暂存区) 中移除文件,但保留工作区中的实际文件。 也就是说: 文件仍然留在硬盘(工作区); 但不再被 Git 跟踪(tracked)。 <file>...:要移除的文件或目录路径。可以指定多个文件,或使用通配符(如 *.log)。 常用选项: --cached:仅从索引移除(必须使用)。 -r 或 --recursive:递归移除目录及其内容(如果指定目录)。


【XR硬件系列】破局“芯”瓶颈:深入浅出解析XR专用芯片的必然性
元宇宙_H2025/10/18

关键词:XR芯片、低延迟、六自由度(6DoF)、异构计算、R1芯片、Motion-to-Photon、功耗、Qualcomm XR 引言:从“玩具”到“工具”的鸿沟 还记得早期的VR头显吗?厚重的机身、粗糙的画面,以及那令人不悦的眩晕感。这些体验上的“硬伤”,曾让XR技术长期徘徊在主流市场的边缘。其核心瓶颈之一,就在于当时的设备大多沿用手机等移动平台的通用芯片(SoC)。 这些“全能但不专精”的芯片,无法满足XR这一“性能吞噬兽”的苛刻需求。今天,我们就来深入探讨,为什么XR的进化之


Redis(66)Redis如何实现分布式锁?
Victor3562025/10/17

Redis 提供了多种方法来实现分布式锁,确保多个进程或机器能够协调地访问共享资源。以下是详细的实现步骤和代码示例。 1. 基于 SET 命令的分布式锁 获取锁 获取锁的核心是使用 SET 命令,并带上 NX 和 EX 选项: NX(Not eXists): 仅当键不存在时才设置键。 EX(EXpire): 设置键的过期时间,防止死锁。 # 获取锁示例 SET mylock <lock_value> NX EX 10 Lua 脚本实现 为了更加原子化,可以使用 Lua 脚本: -- 获取锁

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0