You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:25:15