爬虫+GIS:抓取POI数据并可视化分布——从零开始的实战指南

简介: 本文介绍如何结合Python爬虫与GIS技术,从高德地图API抓取咖啡馆等POI数据,经清洗处理后,利用Folium、GeoPandas实现交互式地图与热力图可视化,涵盖反爬策略、坐标转换与性能优化,助你构建完整的地理数据分析流程。

​免费编程软件「python+pycharm」
链接:https://pan.quark.cn/s/48a86be2fdc0

引言:为什么需要爬虫+GIS?
当你想分析北京所有咖啡馆的分布规律,或研究上海三甲医院的覆盖范围时,单纯的数据表格已无法满足需求。我们需要将地理信息(GIS)与网络爬虫结合,抓取POI(兴趣点)数据并可视化展示。本文将通过Python实现:从高德地图API抓取数据,到用QGIS/Folium生成专业地图的全流程。
探秘代理IP并发连接数限制的那点事 (53).png

一、环境准备:工具与库的选择
1.1 核心工具包

爬虫相关

import requests # HTTP请求
from fake_useragent import UserAgent # 随机User-Agent
import time # 请求间隔控制

数据处理

import pandas as pd # 数据清洗
import json # JSON解析

可视化

import folium # 交互式地图
import matplotlib.pyplot as plt # 统计图表
import geopandas as gpd # 高级GIS分析(可选)

1.2 开发环境建议
Python 3.8+
Jupyter Notebook(交互式开发)
QGIS(专业GIS软件,用于复杂分析)
二、数据抓取:从高德API获取POI
2.1 注册高德开发者账号
访问高德开放平台
创建应用 → 获取Key(示例:your_amap_key)
2.2 构造API请求
def get_poi_data(keywords, city, page_size=20, page_num=1):
"""
高德POI搜索API封装
:param keywords: 搜索关键词(如"咖啡馆")
:param city: 城市限制(如"北京")
:param page_size: 每页结果数(最大50)
:param page_num: 页码
"""
base_url = "https://restapi.amap.com/v3/place/text"
params = {
"key": "your_amap_key", # 替换为你的key
"keywords": keywords,
"city": city,
"types": "", # 可指定分类代码(如"050000"餐饮)
"offset": page_size,
"page": page_num,
"extensions": "base" # 基础信息(all为详细信息)
}

headers = {"User-Agent": UserAgent().random}
response = requests.get(base_url, params=params, headers=headers)

if response.status_code == 200:
    return response.json()
else:
    print(f"请求失败: {response.status_code}")
    return None

2.3 分页抓取与数据合并
def crawl_all_pages(keywords, city, max_pages=10):
all_data = []
for page in range(1, max_pages+1):
print(f"正在抓取第{page}页...")
result = get_poi_data(keywords, city, page_num=page)

    if result and result['status'] == '1':
        pois = result['pois']
        all_data.extend(pois)
        time.sleep(1)  # 礼貌性延迟
    else:
        break

# 转换为DataFrame
df = pd.DataFrame(all_data)
return df[['id', 'name', 'type', 'location', 'address', 'pname', 'cityname']]

示例:抓取北京100家咖啡馆

beijing_coffee = crawl_all_pages("咖啡馆", "北京", max_pages=5)
beijing_coffee.head()

输出示例:

id name ... cityname
0 B0FFFAB5J 星巴克 ... 北京市
1 B0FFG1234 瑞幸咖啡 ... 北京市
...

2.4 坐标处理与保存
高德返回的location是"经度,纬度"格式的字符串:

拆分经纬度

def split_location(row):
lon, lat = row['location'].split(',')
return pd.Series([float(lon), float(lat)])

beijing_coffee[['lon', 'lat']] = beijing_coffee.apply(split_location, axis=1)

保存为CSV

beijing_coffee.to_csv("beijing_coffee.csv", index=False)

三、数据可视化:从基础到进阶
3.1 使用Folium创建交互式地图
import folium

创建基础地图(中心点为北京天安门)

m = folium.Map(location=[39.9087, 116.3975], zoom_start=12)

添加POI点(使用蓝色标记)

for idx, row in beijing_coffee.iterrows():
folium.CircleMarker(
location=[row['lat'], row['lon']],
radius=3,
color='blue',
fill=True,
fill_color='blue'
).add_to(m)

保存为HTML

m.save("beijing_coffee_map.html")

效果:打开HTML文件可看到交互式地图,支持缩放/平移/点击查看详情。

3.2 热力图展示密度分布
from folium.plugins import HeatMap

提取经纬度列表

heat_data = beijing_coffee[['lat', 'lon']].values.tolist()

创建热力图

heat_map = folium.Map(location=[39.9087, 116.3975], zoom_start=12)
HeatMap(heat_data).add_to(heat_map)
heat_map.save("beijing_coffee_heatmap.html")

3.3 结合行政区划分析(使用GeoPandas)

加载北京行政区划数据(需提前下载shapefile)

示例数据源:https://gadm.org/download_country_v3.html

china = gpd.read_file("CHN_adm1.shp")
beijing_boundary = china[china['NAME_1'] == 'Beijing']

绘制基础地图

fig, ax = plt.subplots(figsize=(10, 8))
beijing_boundary.plot(ax=ax, color='lightgray', edgecolor='black')

绘制POI散点

plt.scatter(
beijing_coffee['lon'],
beijing_coffee['lat'],
s=10,
alpha=0.6,
color='red'
)
plt.title("北京咖啡馆分布")
plt.xlabel("经度")
plt.ylabel("纬度")
plt.show()

四、进阶技巧:提升抓取效率与质量
4.1 代理IP池实现

简易代理测试函数

def test_proxy(proxy):
try:
proxies = {"http": f"http://{proxy}", "https": f"https://{proxy}"}
response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=5)
if "origin" in response.json():
return True
except:
return False

示例:从文件读取代理列表并测试

with open("proxies.txt") as f:
proxies = [line.strip() for line in f]

valid_proxies = [p for p in proxies if test_proxy(p)]
print(f"可用代理数: {len(valid_proxies)}")

4.2 异常处理与重试机制
from requests.exceptions import RequestException

def safe_request(url, params, maxretries=3):
for
in range(max_retries):
try:
headers = {"User-Agent": UserAgent().random}
response = requests.get(url, params=params, headers=headers, timeout=10)
if response.status_code == 200:
return response.json()
except RequestException:
time.sleep(2) # 等待后重试
return None

4.3 多关键词抓取策略
keywords_list = ["咖啡馆", "星巴克", "瑞幸咖啡", "Costa"]
all_data = []

for keyword in keywords_list:
print(f"正在抓取关键词: {keyword}")
data = crawl_all_pages(keyword, "北京", max_pages=3)
all_data.append(data)
time.sleep(3) # 避免频繁请求

合并数据

final_df = pd.concat(all_data, ignore_index=True)
final_df.to_csv("beijing_all_coffee.csv", index=False)

五、常见问题Q&A
Q1:被网站封IP怎么办?
A:立即启用备用代理池,建议使用隧道代理(如站大爷IP代理),配合每请求更换IP策略。对于高德API,合理控制请求频率(建议间隔1-2秒),避免短时间内大量请求。

Q2:如何提高数据抓取速度?
A:

使用多线程/异步请求(如aiohttp库)
分布式爬虫(Scrapy+Redis)
预生成代理IP池
避开高峰时段抓取
Q3:高德API返回"无权限"错误?
A:检查:

API Key是否正确
是否开通了对应服务的权限(如Web服务API)
是否超出每日调用配额(免费版5000次/天)
Q4:如何获取更详细的POI信息?
A:在API请求中设置extensions=all,可获取营业时间、评分等额外字段,但会消耗更多配额。

Q5:坐标系不匹配怎么办?
A:高德使用GCJ-02坐标系(火星坐标),如需转换为WGS-84(GPS坐标),可使用pyproj库:

from pyproj import Transformer

transformer = Transformer.from_crs("EPSG:4490", "EPSG:4326") # GCJ02→WGS84
lon, lat = transformer.transform(39.9087, 116.3975)

结语:从数据到洞察的完整链路
通过本文,你已掌握:

使用Python爬取高德POI数据
数据清洗与坐标处理
基础到高级的可视化方法
反爬策略与性能优化技巧
下一步可尝试:

结合人口数据做空间相关性分析
使用机器学习预测POI分布
开发Web应用实时展示地图(Django+Leaflet)
数据采集只是开始,真正的价值在于通过地理空间分析发现隐藏的业务规律。

目录
相关文章
|
11天前
|
人工智能 JavaScript Linux
2026最新OpenClaw安装教程:零基础手把手教学,5分钟解锁会干活的小龙虾
官方推荐的安装方式,涵盖Windows、macOS、Linux三大系统——所有操作仅需约 5 分钟。完成后,您将拥有一个正在运行的网关、已配置的身份验证以及一个可正常使用的聊天会话。
|
安全 Unix Linux
VMware Workstation 17.6.3 发布下载,现在完全免费无论个人还是商业用途
VMware Workstation 17.6.3 发布下载,现在完全免费无论个人还是商业用途
127366 65
|
4月前
|
测试技术 芯片 C++
Python 安装
本文介绍Windows下安装Python 3.14.2的方法,包括版本选择、自定义安装选项、环境变量配置及安装验证,帮助用户快速搭建Python环境。
2004 8
Python 安装
|
11月前
|
数据采集 文字识别 JavaScript
视觉分析开发范例:Puppeteer截图+计算机视觉动态定位
本文介绍了在现代互联网中,传统DOM爬虫难以应对动态加载和视觉驱动内容的问题,并提出了“视觉爬虫”的解决方案。通过Puppeteer实现浏览器自动化,结合计算机视觉技术完成页面元素的动态定位与信息提取。文章对比了DOM爬虫与视觉爬虫的技术特点,展示了基于Node.js的核心代码示例,用于小红书平台的视频搜索、播放及截图处理。最后指出,视觉爬虫能够突破传统限制,在强JS渲染和动态内容场景中更具优势,为数据采集提供了新方向。
476 1
视觉分析开发范例:Puppeteer截图+计算机视觉动态定位
|
10月前
|
数据采集
美团外卖商家数据采集软件,提取电话号手机号评分地址,销量评价内容【autojs版】
这是一款基于AutoJS开发的美团外卖商家数据采集工具,可自动抓取商家名称、电话、评分、地址、月销量及评价内容等信息。支持多页滚动加载与详细数据采集
|
SQL 监控 数据处理
实时计算 Flink版产品使用合集之开启 MiniBatch 优化会引入乱序问题如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
372 0
|
9月前
|
JSON Java 数据安全/隐私保护
qq群成员qq号一键提取, 不加群就可以提取QQ群成员, qq群成员提取器
完整的QQ群成员提取功能,包括登录验证、成员获取、数据解析和导出功能。代码结构清晰
|
缓存 算法 测试技术
|
10月前
|
人工智能 5G 定位技术
如何使用基站查询API帮你解析地理位置?
随着“新基建”战略推进,我国已建成全球领先的移动通信网络。基于基站数据的LBS定位服务成为各行业数字化转型的重要工具。探数平台基站查询API整合三大运营商数据,提供高精度、低延迟的地理位置查询服务,广泛应用于位置推荐、物流追踪等领域。本文详细介绍该API的核心功能、返回字段及调用流程,并通过Python示例展示使用方法。未来,随着5G和AI技术发展,基站定位将迈向厘米级精度,赋能自动驾驶、工业物联网等前沿领域,助力开发者抢占位置经济的战略高地。
2824 1
|
敏捷开发 监控 数据可视化
项目管理仪表盘详解:高效团队协作从这里开始
从IT开发到工程建设、从市场营销到研发项目,仪表盘都可以通过整合和可视化关键数据,帮助团队协作、监控进度、优化资源配置,从而确保项目按时、高质量交付。
752 0
项目管理仪表盘详解:高效团队协作从这里开始