如何不使用Selenium,用Beautiful Soup爬取Leaflet弹窗内容
解决Leaflet弹窗文本爬取问题
因为Leaflet地图的弹窗内容是JavaScript动态生成的,静态HTML源码里不会直接包含leaflet-marker-pane元素及其文本,所以用requests+BeautifulSoup直接爬取页面无法获取。针对你的批量爬取需求,推荐以下两种高效方案:
方案1:提取页面静态源码中的隐藏数据
很多网站会把动态渲染所需的数据源提前嵌入到页面的<script>标签里,你可以尝试:
- 打开目标页面的源码,搜索包含坐标、地址或弹窗文本的JS变量(比如关键词:
lat、lng、popup、lokasi等)。 - 用BeautifulSoup提取对应
<script>标签的内容,再用正则表达式匹配所需数据。
示例代码(假设页面JS中包含弹窗绑定代码):
import re # ... 你的原有代码 ... if page.status_code == 200: page_soup = BeautifulSoup(page.content, 'html.parser') # 提取所有script标签内容 scripts = page_soup.find_all('script') popup_pattern = re.compile(r'bindPopup\(\'(.*?)\'\)') for script in scripts: if script.string: match = popup_pattern.search(script.string) if match: leaf_text = match.group(1).replace('<br>', '\n') print(leaf_text) break
方案2:直接调用弹窗数据的API接口
当点击Leaflet图标时,页面通常会发送AJAX请求获取弹窗内容,你可以通过抓包找到这个接口:
- 打开浏览器开发者工具(F12),切换到「Network」标签。
- 点击Leaflet图标触发弹窗,观察新出现的XHR/fetch请求,找到返回弹窗数据的接口。
- 分析该接口的请求参数(通常是URL中的学校UUID),直接用requests批量请求这个接口。
示例代码(假设接口为getProfilLokasi,参数为学校ID):
# ... 你的原有代码 ... if page.status_code == 200: # 提取URL中的学校UUID school_id = href.split('/')[-1] # 构造API请求URL(需替换为实际抓包得到的接口) api_url = f'https://sekolah.data.kemdikbud.go.id/index.php/Chome/getProfilLokasi?id={school_id}' api_response = requests.get(api_url, headers=headers) if api_response.status_code == 200: # 假设返回JSON格式数据 popup_data = api_response.json() # 根据实际返回结构提取文本,比如: leaf_text = popup_data['content'] print(leaf_text)
注意事项
- 批量爬取时,建议添加合理的请求间隔(比如
time.sleep(random.uniform(0.5, 1.5))),避免触发网站反爬机制。 - 若API接口需要额外参数(如csrf token),可从页面源码中提取对应参数后再构造请求。
内容的提问来源于stack exchange,提问作者Tosh_gitonga
相关产品推荐
相关产品推荐

