如何让Puppeteer代码等待指定网络响应事件触发后再结束?
解决Puppeteer等待特定网络响应的问题
你的问题核心是Do()方法在目标响应返回前就执行完毕,导致result为空。可以通过TaskCompletionSource创建一个等待信号,让方法必须等到捕获到指定响应后才继续执行,具体修改如下:
修改后的完整代码
private async void button1_Click(object sender, EventArgs e) { var result = await Do(); textBox1.AppendText(result ?? "未捕获到目标响应"); } private async Task<string> Do() { using var browser = await Puppeteer.LaunchAsync(); var page = await browser.NewPageAsync(); var tcs = new TaskCompletionSource<string>(); page.Response += async (s, e) => { if (e.Response.Request.Url == "URL_1") { try { var responseText = await e.Response.TextAsync(); tcs.TrySetResult(responseText); } catch (Exception ex) { tcs.TrySetException(ex); } } }; // 同时等待页面加载和目标响应 var goToTask = page.GoToAsync("URL_2"); var responseTask = await Task.WhenAny(tcs.Task, goToTask); // 页面加载完成后仍等待一段时间,避免响应延迟 if (responseTask == goToTask) { var timeoutTask = Task.Delay(5000); responseTask = await Task.WhenAny(tcs.Task, timeoutTask); if (responseTask == timeoutTask) { tcs.TrySetResult("等待目标响应超时"); } } return await tcs.Task; }
关键说明
- TaskCompletionSource
:手动控制任务的完成状态,捕获到目标响应时,通过 TrySetResult标记任务完成并传入响应内容。 - Task.WhenAny:同时监听页面加载任务和响应捕获任务,避免页面加载完成后直接结束方法。
- 超时处理:增加5秒超时逻辑,防止因网络问题导致程序无限等待。
- using声明browser:替代全局变量,自动管理浏览器资源,避免手动关闭时的时序问题。
这样修改后,Do()方法会确保拿到目标响应结果(或超时信息)后才返回,不会出现提前结束导致result为空的情况。
内容的提问来源于stack exchange,提问作者user23220579
相关产品推荐
相关产品推荐

