VB.NET WinForms中通过WebView2获取谷歌地图两地距离的实现问题
不需要更换WebView2控件,通过JS与.NET交互即可实现数据提取
WebView2完全支持与网页JavaScript双向交互,足以满足你提取谷歌地图路径数据的需求,无需更换控件。以下是具体实现步骤:
1. 确保WebView2初始化完成并启用交互
首先要保证CoreWebView2对象初始化完成,同时注册一个供JavaScript调用的.NET对象,用于传递提取到的数据:
Imports System.Text Imports Microsoft.Web.WebView2.Core Imports System.Threading.Tasks Public Class Form1 ' 定义供JS调用的辅助类,用于传递数据到.NET端 Public Class DotNetRouteHelper Private _parentForm As Form1 Public Sub New(form As Form1) _parentForm = form End Sub ' JS将调用此方法传递路径数据 Public Sub SendRouteData(location1 As String, location2 As String, distance As Double) ' 回到UI线程更新控件(JS调用可能在非UI线程) _parentForm.Invoke(Sub() _parentForm.txtLocation1.Text = location1 _parentForm.txtLocation2.Text = location2 _parentForm.txtDistance.Text = distance.ToString("F2") ' 保留两位小数 ' 此处添加存入数据库的逻辑 ' Example: SaveRouteToDB(location1, location2, distance) End Sub) End Sub End Class Private Async Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' 初始化CoreWebView2 Await MyWebView_.EnsureCoreWebView2Async(Nothing) ' 注册.NET对象到JS环境,命名为dotnetRouteHelper MyWebView_.CoreWebView2.AddHostObjectToScript("dotnetRouteHelper", New DotNetRouteHelper(Me)) End Sub
2. 注入JavaScript提取地图路径数据
谷歌地图生成路径后,相关数据会动态渲染到页面DOM中,我们可以通过注入JS监听页面变化,提取起点、终点和距离:
Private Sub MyWebView_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs) Handles MyWebView_.NavigationCompleted If e.IsSuccess Then ' 注入提取数据的JS代码 Dim extractJs As String = @" function getRouteInfo() { // 提取起点和终点(基于谷歌地图当前DOM结构,若后续页面更新需调整选择器) const waypointElements = document.querySelectorAll('.gm2-subtitle-alt-2'); if (waypointElements.length < 2) return; const startLoc = waypointElements[0].textContent.trim(); const endLoc = waypointElements[1].textContent.trim(); // 提取距离数值 const distanceElement = document.querySelector('.section-directions-trip-distance'); if (!distanceElement) return; const distanceText = distanceElement.textContent.trim(); const distanceValue = parseFloat(distanceText.match(/[\d\.]+/)[0]); // 提取数字部分 // 调用.NET端方法传递数据 if (window.chrome?.webview?.hostObjects?.dotnetRouteHelper) { window.chrome.webview.hostObjects.dotnetRouteHelper.SendRouteData(startLoc, endLoc, distanceValue); } } // 监听页面DOM变化,确保路径生成后能及时提取数据 const domObserver = new MutationObserver(() => { getRouteInfo(); }); domObserver.observe(document.body, { childList: true, subtree: true }); // 页面加载完成后延迟执行一次,确保DOM渲染完毕 setTimeout(getRouteInfo, 1500); " ' 执行注入的JS代码 MyWebView_.CoreWebView2.ExecuteScriptAsync(extractJs) End If End Sub
3. 修正现有搜索导航逻辑
你当前的代码未正确使用构建的URL,且应使用谷歌地图的路径查询URL(/dir/)而非普通搜索,确保直接进入路径页面:
Private Sub txtSearch_KeyDown(sender As Object, e As KeyEventArgs) Handles txtSearch.KeyDown If e.KeyCode = Keys.Enter Then Try Dim routeUrl As New StringBuilder("https://www.google.com/maps/dir/") Dim inputParts = txtSearch.Text.Split({" to ", " -> "}, StringSplitOptions.RemoveEmptyEntries) If inputParts.Length <> 2 Then MessageBox.Show("请输入格式:起点 to 终点") Return End If ' 对地址进行URL编码,避免特殊字符问题 routeUrl.Append(Uri.EscapeDataString(inputParts(0)) & "/" & Uri.EscapeDataString(inputParts(1))) MyWebView_.CoreWebView2.Navigate(routeUrl.ToString()) Catch ex As Exception MessageBox.Show("加载路径失败:" & ex.Message) End Try End If End Sub
注意事项
- 谷歌地图的DOM结构可能会随版本更新变化,如果后续无法提取数据,需检查页面元素的类名并调整JS中的选择器。
- 数据库操作需确保线程安全,建议使用异步数据库方法或在UI线程中执行。
- 确保已安装WebView2 Runtime,否则控件无法正常初始化。
内容的提问来源于stack exchange,提问作者Solution Hall
相关产品推荐
相关产品推荐

