谷歌地图地图集抓取技术求助:如何获取加拿大曼尼托巴省大麻零售商名称与地址并导出至Excel
问题分析
你的代码返回空列表的核心原因是这个Google My Map页面的内容是通过JavaScript动态渲染的:requests.get()只能获取到页面的静态HTML骨架,那些包含商家名称和地址的元素(fO2voc-jRmmHf-MZArnb-Q7Zjwb、qqvbed-p83tee-lTBxed)是页面加载后由JS动态生成的,静态HTML里根本没有这些元素,所以BeautifulSoup自然找不到。
下面给你两种符合需求的解决方案,优先推荐你熟悉的JSON数据提取思路:
方法1:提取页面隐藏的JSON数据(推荐,适配你的JSON请求习惯)
Google My Map通常会把所有标记数据打包在页面的某个<script>标签里,你可以直接提取这个JSON数据,不需要解析零散的HTML元素:
示例代码
import requests import re import json import pandas as pd # 请求目标页面 url = "https://www.google.com/maps/d/u/0/viewer?mid=1jTYtNQgB0CVC27Bn_xIsFGeVuCh_KCdR&ll=49.85504530000007%2C-97.11150419999998&z=8" response = requests.get(url) html_content = response.text # 匹配存储地图数据的script标签 pattern = re.compile(r'var window\.__gmWizData__ = (.*?);\s*</script>', re.DOTALL) match = pattern.search(html_content) if match: # 解析JSON格式的地图数据 gm_data = json.loads(match.group(1)) # 提取所有标记点的核心数据 markers = gm_data['viewerData']['map']['features'] # 整理商家名称与地址 retailer_data = [] for marker in markers: name = marker['properties']['title'] # 地址通常在snippet字段中,部分带有HTML换行,这里做简单提取 raw_address = marker['properties']['snippet'] address = raw_address.split('<br>')[0] if '<br>' in raw_address else raw_address retailer_data.append({ 'Name': name, 'Address': address }) # 导出到Excel文件 df = pd.DataFrame(retailer_data) df.to_excel('manitoba_cannabis_retailers.xlsx', index=False) print("数据已成功导出到Excel!") else: print("未找到地图数据,请检查页面结构是否有更新。")
注意事项
如果window.__gmWizData__变量找不到,可以在页面源码里搜索类似的关键字(比如__INITIAL_STATE__),Google偶尔会调整数据存储的变量名。
方法2:使用浏览器自动化工具(Selenium)
如果JSON数据结构频繁变化,或者你不想处理正则匹配,可以用Selenium模拟浏览器加载页面,等待动态元素渲染完成后再提取数据:
示例代码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import pandas as pd # 初始化Chrome浏览器(需提前下载对应版本的chromedriver) driver = webdriver.Chrome() url = "https://www.google.com/maps/d/u/0/viewer?mid=1jTYtNQgB0CVC27Bn_xIsFGeVuCh_KCdR&ll=49.85504530000007%2C-97.11150419999998&z=8" driver.get(url) # 等待页面动态元素加载完成 wait = WebDriverWait(driver, 10) wait.until(EC.presence_of_element_located((By.CLASS_NAME, "qqvbed-p83tee-lTBxed"))) # 提取商家名称与地址 names = driver.find_elements(By.CLASS_NAME, "qqvbed-p83tee-lTBxed") addresses = driver.find_elements(By.CLASS_NAME, "fO2voc-jRmmHf-MZArnb-Q7Zjwb") # 整理数据并导出 retailer_data = [{'Name': n.text, 'Address': a.text} for n, a in zip(names, addresses)] df = pd.DataFrame(retailer_data) df.to_excel('manitoba_cannabis_retailers.xlsx', index=False) # 关闭浏览器 driver.quit() print("数据已成功导出到Excel!")
注意事项
- 需要下载与浏览器版本匹配的驱动(比如Chrome的chromedriver)
- 频繁请求可能触发Google的反爬机制,建议添加请求间隔或使用代理
额外建议
- 无论用哪种方法,都建议在请求时添加浏览器类型的
headers,模拟真实用户请求,降低被封禁的风险 - 提取数据后可以先打印几条样本,确认名称和地址的格式是否正确,部分商家的地址可能需要额外的文本清洗
内容的提问来源于stack exchange,提问作者John_Muir
相关产品推荐
相关产品推荐

