资讯动态

C#爬虫03:使用PuppeteerSharp模拟浏览器通过Cloudflare 挑战,提取出Cookie值

发布时间:2026/8/27 12:58:30 来源:尧图企业网站定制
一、第三方库PuppeteerSharp二、代码解析class Program { static async Task Main() { // 指定浏览器驱动如果没有可以官网下载 var browser await Puppeteer.LaunchAsync(new LaunchOptions { Headless false, // true为无头后台运行不弹出窗口适合正式环境false适合调试可以看到跳转情况 ExecutablePath C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe }); //打开一个空白页 var page await browser.NewPageAsync(); // 访问网站自动等待CF验证跳转拿到第一个Cookie1 await page.GoToAsync(https://xxxx.com, WaitUntilNavigation.Networkidle2); //打开一个新网站根据第一个Cookie1执行搜索触发拿到所有Cookie await page.EvaluateExpressionAsync(window.location.href /search?keyword搜索关键字); // 确保 cookie 写入完成 await Task.Delay(5000); // 直接获取浏览器内所有有效Cookie var puppeteerCookies await page.GetCookiesAsync(); foreach (var c in puppeteerCookies) { Console.WriteLine(JsonConvert.SerializeObject(c)); } //关闭浏览器 await browser.CloseAsync(); } }三、封装namespace ConsoleApp2.EasyDLL { public class EasyPuppeteer : IAsyncDisposable { private bool _Headless false; private string _ExecutablePath string.Empty; private string _InitialUrl string.Empty; private IBrowser _Browser null; private IPage _Page null; /// summary /// 初始化函数 /// 示例入参await using EasyPuppeteer easypu new EasyPuppeteer(url);【使用await using退出时自动释放】 /// /summary /// param nameInitialUrl初始跳转链接/param /// param nameExecutablePath浏览器驱动路径如果没有可以下载/param /// param nameHeadless是否无头模式是则不弹出浏览器否则可以看到跳转情况建议为否/param public EasyPuppeteer(string InitialUrl , string ExecutablePath , bool Headless false) { _ExecutablePath string.IsNullOrEmpty(ExecutablePath) ? C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe : _InitialUrl InitialUrl; _Headless Headless; _Browser Puppeteer.LaunchAsync(new LaunchOptions { Headless _Headless, // true为无头后台运行不弹出窗口适合正式环境false适合调试可以看到跳转情况 ExecutablePath _ExecutablePath }).Result; _Page _Browser.NewPageAsync().Result; if (!string.IsNullOrEmpty(InitialUrl)) { _Page.GoToAsync(InitialUrl, WaitUntilNavigation.Networkidle2).Wait(); } _Page.SetViewportAsync(null).Wait();//设置窗口大小为最大 } /// summary /// 跳转到指定网站 /// /summary public async Taskbool GoToAsync(string url) { try { await _Page.GoToAsync(url, WaitUntilNavigation.Networkidle2); return true; } catch (Exception ex) { Console.WriteLine($【跳转错误】{ex.Message}); } return false; } /// summary /// 获取当前页面情况 /// /summary /// returns/returns public async TaskEasyPuppeteerDetailDto GetPageDetailAsync() { EasyPuppeteerDetailDto output new EasyPuppeteerDetailDto(); output.Page _Page; output.Browser _Browser; try { output.HTML await _Page.GetContentAsync(); var cookiesList (await _Page.GetCookiesAsync()).ToList(); StringBuilder sb new StringBuilder(); foreach (var cookie in cookiesList) { sb.Append(${cookie.Name}{cookie.Value};); } output.Cookies sb.ToString(); return output; } catch (Exception ex) { Console.WriteLine($【获取页面错误】{ex.Message}); } return output; } /// summary /// 通过js点击某个按钮 /// /summary /// param namexpath这个按钮在当前界面的xpath/param /// returns/returns public async Taskbool ClickAsync(string xpath) { try { string inputs $document.evaluate({xpath},document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue.click(); await _Page.EvaluateExpressionAsync(inputs); } catch (Exception ex) { Console.WriteLine($【点击错误】{ex.Message}); return false; } return true; } /// summary /// 接口捕捉 /// 例如打开界面后界面会调动https://live.douyin.com/webcast/ranklist/audience接口此时传入部分url如“/webcast/ranklist/audience”即可捕捉到它的请求参数、请求头、响应内容等关键内容 /// /summary public async TaskCaptureInterfaceDto CaptureInterface(string url) { var page _Page; // 等待目标请求 var request await page.WaitForRequestAsync( req req.Url.Contains(url),//模糊匹配 new WaitForOptions { Timeout 10000 } ); // 等待目标响应 var response await page.WaitForResponseAsync( req req.Url.Contains(url), new WaitForOptions { Timeout 10000 } ); // 返回参数 CaptureInterfaceDto result new CaptureInterfaceDto(); //请求相关 if (request ! null) { Dictionarystring, string headers new Dictionarystring, string(); result.Url request.Url; result.Method request.Method; // 请求头 foreach (var header in request.Headers) { headers.TryAdd(header.Key, header.Value); } result.HeadersDict headers; // 请求参数 if (result.Url.Contains(?)) { var param result.Url.Split(?)[1]; var paramList param.Split(); Dictionarystring, string paramDict new Dictionarystring, string(); foreach (var item in paramList) { var key item.Split()[0]; var value item.Split()[1]; paramDict.Add(key, value); } result.ParamDict paramDict; } //请求体 result.PostBody request.PostData; } // 响应相关 if (response ! null) { //响应状态码和结果 result.Status response.Status; result.Result await response.TextAsync(); } return result; } /// summary /// 打印接口捕捉结果 /// /summary public string PrintCaptureInterfaceDto(CaptureInterfaceDto dto) { StringBuilder sb new StringBuilder(); if (dto null) { sb.AppendLine(CaptureInterfaceDto 对象为 null); return sb.ToString(); } sb.AppendLine( CaptureInterfaceDto 信息 ); sb.AppendLine($Url: {dto.Url}); sb.AppendLine($Method: {dto.Method?.Method ?? NULL}); // 打印请求参数 sb.AppendLine(\n--- 请求参数 ---); if (dto.ParamDict ! null dto.ParamDict.Count 0) { foreach (var param in dto.ParamDict) { sb.AppendLine($ {param.Key}: {param.Value}); } } else { sb.AppendLine( 无请求参数); } // 打印请求头 sb.AppendLine(\n--- 请求头 ---); if (dto.HeadersDict ! null dto.HeadersDict.Count 0) { foreach (var header in dto.HeadersDict) { sb.AppendLine($ {header.Key}: {header.Value}); } } else { sb.AppendLine( 无请求头); } sb.AppendLine($\nStatus: {(int)dto.Status} {dto.Status}); // 打印响应结果 sb.AppendLine(\n--- 响应结果 ---); if (!string.IsNullOrEmpty(dto.Result)) { sb.AppendLine(dto.Result); } else { sb.AppendLine( 响应结果为空); } sb.AppendLine(); Console.WriteLine(sb.ToString()); return sb.ToString(); } #region 非核心接口 /// summary /// 手动关闭 /// /summary /// returns/returns public async Taskbool CloseAsync() { try { await _Browser.CloseAsync(); return true; } catch (Exception ex) { Console.WriteLine($【错误信息】关闭时错误{ex.Message}); return false; } } /// summary /// 释放实例 /// /summary /// returns/returns public async ValueTask DisposeAsync() { await CloseAsync(); } #endregion } public class CaptureInterfaceDto { /// summary /// 请求url /// /summary public string Url { get; set; } /// summary /// 请求方法 /// /summary public HttpMethod Method { get; set; } /// summary /// 请求参数 /// /summary public Dictionarystring, string ParamDict { get; set; } /// summary /// 请求头 /// /summary public Dictionarystring, string HeadersDict { get; internal set; } /// summary /// 请求体Body /// /summary public string PostBody { get; internal set; } /// summary /// 响应状态 /// /summary public HttpStatusCode Status { get; internal set; } /// summary /// 响应结果 /// /summary public string Result { get; internal set; } } public class EasyPuppeteerDetailDto { /// summary /// HTML文本 /// /summary public string HTML { get; set; } string.Empty; /// summary /// Cookie /// /summary public string Cookies { get; set; } string.Empty; /// summary /// 页面 /// /summary public IPage Page { get; set; } /// summary /// 浏览器 /// /summary public IBrowser Browser { get; set; } } }

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价