webview2 多层嵌套执行js

整体逻辑

首先在需要用webview的地方初始化InitializeWebView

int nlength=2; List webViewList = new List();

private Microsoft.Web.WebView2.WinForms.WebView2 webView21;

qflagurl = true;
							qflag = false;
							urlSet.Clear();
							listBox1.Items.Clear();
							string url = txtwanneng.Text.ToString().Trim();
							Sharing.setlinks(url); 
							InitializeWebView(); 
							Uri uri;
							if (Uri.TryCreate(url, UriKind.Absolute, out uri))
							{
								webView21.Source = uri;
								 Sharing.setTips("web通道适配中30s未响应 则匹配失败......"); 
							}
							else
							{
								MessageBox.Show("链接输入有误,无法解析");
							}

InitializeWebView()代码如下:

		private async void  InitializeWebView()
        {
			webView21 = new WebView2();
			webViewList.Add(webView21); 
			webView21.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;
			await webView21.EnsureCoreWebView2Async();
        }

初始化母体webview21 并且绑定事件WebView_CoreWebView2InitializationCompleted

		private void WebView_CoreWebView2InitializationCompleted(object sender, EventArgs e)
        { 
			if (webView21.CoreWebView2 != null)
            {
				// 添加 NavigationStarting 事件处理程序
				webView21.CoreWebView2.NavigationStarting += CoreWebView2_NavigationStarting;
				// 订阅请求拦截事件  
				webView21.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
				webView21.CoreWebView2.WebResourceRequested += CoreWebView2_WebResourceRequested;
			}
		}

CoreWebView2_NavigationStarting代码如下:

	private void CoreWebView2_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e)
        {
            // 在此处拦截请求并处理
            string url = e.Uri;
            Console.WriteLine($"Navigating to: {url}");
        }

CoreWebView2_WebResourceRequested代码如下:

private async void CoreWebView2_WebResourceRequested(object sender, CoreWebView2WebResourceRequestedEventArgs e)
        {
			//e.Request.Headers.SetHeader("Referer", "https://www.nanhuyt.com/v/135-1-1.html"); 
			// 获取请求
			var request = e.Request; 
            var url = request.Uri; var tet = ""; 
			if (url != txtwanneng.Text.ToString().Trim())
            {
				if (url != null && (url.EndsWith(".m3u8") || url.Contains(".m3u8")) && qflagurl == true)
				{
					Match match = Regex.Match(url, @"http((?!http).)*m3u8", RegexOptions.Singleline);
					if (match.Success)
					{
						url = match.Value;
					}
					urlSet.Add(url);				 
					UpdateListBox();
					lock (queueLock)
					{
						requestQueue.Enqueue(url);
					}
					// 开始处理队列
					ProcessQueue();


				}
				else if ((url.EndsWith("mp4") || url.EndsWith(".mp4")) && qflagurl == true)
				{

					Match match = Regex.Match(url, @"http((?!http).)*\.mp4", RegexOptions.Singleline);
					if (match.Success)
					{
						url = match.Value;
					}
					urlSet.Add(url);
					UpdateListBox();
					//issuccessqiantaom3u8 = true;
					//qflag = false;
					lock (queueLock)
					{
						requestQueue.Enqueue(url);
					}
					// 开始处理队列
					ProcessQueue();
				}
				else if ((url.Contains("mp4")) && qflagurl == true) { 
					urlSet.Add(url);
					UpdateListBox();
					//issuccessqiantaom3u8 = true;
					//qflag = false;
					lock (queueLock)
					{
						requestQueue.Enqueue(url);
					}
					// 开始处理队列
					ProcessQueue();
				}
				else if (url == "http://127.0.0.1/")
				{
					MessageBox.Show("触发回环地址,此网站无法抓取噢");
							}
				else
				{
					
				}
            }
			if (urlSet.Count == 0|| !issuccessqiantaom3u8)
            {
				
                List<string> iframeSources = await GetAllIFrameSourcesAsync();
                // 使用逗号分隔连接所有的 src 字符串   // 将连接后的字符串再次拆分成数组
                string joinedSources = string.Join(",", iframeSources);
                string[] sourcesArray = joinedSources.Split(',');
                if (sourcesArray.Length > 1 && qflag == false|| sourcesArray.Length > nlength)//在这调控空的iframe
                {
					nlength = sourcesArray.Length;
                    qflag = true;//会一直抓 解决办法1, 多抓两次,2 抓到了才结束 3等待完成
                    foreach (var src in sourcesArray)
                    {
                        Console.WriteLine($"IFrame source: {src}");
						var needurl = src;
						Match match = Regex.Match(src, @"http[^""]*", RegexOptions.Singleline);
						if (match.Success)
						{
							needurl = match.Value;
						 
						} 
						//不是本域名的嵌套应该都进去拦截看看 不管有几个链接,加载都应该单开一个重新加载
						if (needurl != null && (needurl != txtwanneng.Text.ToString().Trim()) )//在这调控不是m3u8或者mp4的iframe 获取嵌套带url的
						{

							tet = "嵌套加载获取中....\n";
							Sharing.setTips(tet);
							Widget.Ssp.Invoke(Form1.PSetTxt, new object[]
							{
									1,
							"嵌套加载获取中...."
							});
							
                            urlSet.Clear();
                            var newWebView = new WebView2(); 
							webViewList.Add(newWebView);
							newWebView.CoreWebView2InitializationCompleted += NewWebView_CoreWebView2InitializationCompleted;
							await newWebView.EnsureCoreWebView2Async();  
                            // 将字符串 URL 转换为 Uri 对象
                            Uri quri;
                            if (Uri.TryCreate(needurl, UriKind.Absolute, out quri))
                            {
								newWebView.Source = quri;
                            }
                            else
                            {
                                Console.WriteLine(needurl);
                                MessageBox.Show("嵌套iframe链接出错,无法抓取");
                            }
                        }
                        // 这里可以进一步处理每个 iframe 的 src 属性,例如显示到界面上或者进行其他操作
                    }
                }
            }
			//iframelist获取 

		}

GetAllIFrameSourcesAsync代码如下:

	private async Task<List<string>> GetAllIFrameSourcesAsync()
		{
			
			List<string> iframeSources = new List<string>(); 
			try
			{
				string script = @"
            var iframes = document.getElementsByTagName('iframe');
            var sources = [];
            for (var i = 0; i < iframes.length; i++) {
                sources.push(iframes[i].src);
            }
            sources;
        ";
				var result = await webView21.ExecuteScriptAsync(script); 
				if (result != null)
				{ 
                    iframeSources.Add(result); 
                }
			}
			catch (Exception ex)
			{
				Console.WriteLine($"Error getting iframe sources: {ex.Message}");
			}

			return iframeSources;
		}

通过绑定请求拦截事件,拦截我们需要的url

我在这里执行js代码的时候 List iframeSources = await GetAllIFrameSourcesAsync();,一开始是webView21.ExecuteScriptAsync(script);

但是在后面我获取到需要的url的时候new了一个新的webview

var newWebView = new WebView2();  					webViewList.Add(newWebView); 					newWebView.CoreWebView2InitializationCompleted += NewWebView_CoreWebView2InitializationCompleted; 					await newWebView.EnsureCoreWebView2Async(); 并且绑定了这个事件

现在修改成需要GetAllIFrameSourcesAsync中用new的webview执行js

List iframeSources = await GetAllIFrameSourcesAsync(newWebView);是在 var newWebView = new WebView2();之前执行的,新的webview是通过NewWebView_CoreWebView2InitializationCompleted;事件重新绑定CoreWebView2_WebResourceRequested然后执行到GetAllIFrameSourcesAsync 获取到iframe的src才会new webview,注意这个逻辑,并重新修改代码

 List<string> iframeSources = await GetAllIFrameSourcesAsync(webViewList[0]);应该是这样传入进去啊,但是在   var newWebView = new WebView2(); 
							webViewList.Add(newWebView);有可能每次都会新添加 怎么修改webViewList[0]每次都是传入新添加的微博view

List iframeSources = await GetAllIFrameSourcesAsync(webViewList[webViewList.Count - 1]);