wpf使用CefSharp.OffScreen模拟网页登录,并获取身份cookie

目录

    • 框架信息:
    • MainWindow.xaml
    • MainWindow.xaml.cs
    • 爬取逻辑
    • 模拟登录
    • 拦截请求
    • Cookie获取 CookieVisitorHandle

框架信息:

CefSharp.OffScreen.NETCore 119.1.20

在这里插入图片描述

MainWindow.xaml

<Window x:Class="Wpf_CHZC_Img_Identy_ApiDataGet.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Wpf_CHZC_Img_Identy_ApiDataGet"
        mc:Ignorable="d"
        Loaded="Window_Loaded"
        WindowStartupLocation="CenterScreen"
        Title="XXXX数据爬取(风险作业)" Height="900" Width="1000"  >
    <Window.Resources>
        <Style TargetType="DockPanel" x:Key="DockPanel1">
            <Setter Property="Margin" Value="0,20,0,0"></Setter>
            <Setter Property="FlowDirection" Value="LeftToRight"></Setter>
            <!--<Setter Property="DockPanel." Value="LeftToRight"></Setter>-->
        </Style>
        <Style TargetType="StackPanel" x:Key="StackPanel1">
            <Setter Property="Margin" Value="0,15,0,0"></Setter>
            <Setter Property="Orientation" Value="Horizontal"></Setter>
            <!--<Setter Property="DockPanel." Value="LeftToRight"></Setter>-->
        </Style>
        <Style TargetType="Label" x:Key="Label2">
            <Setter Property="FontSize" Value="18"></Setter>
        </Style>
        <Style TargetType="ComboBox"  >
            <Setter Property="FontSize" Value="18"></Setter>
        </Style>
    </Window.Resources>
    <Grid Margin="20">
        <StackPanel   >
            <Label  Content="设置时间点执行爬取数据,爬取成功发送到甲甲转发系统" FontWeight="Bold" FontSize="24"/>
            <StackPanel  Style="{StaticResource StackPanel1}"  >
                <Label Style="{StaticResource Label2}">时间1,时分:</Label>
                <ComboBox  Name="comboxHour"   Width="100" SelectionChanged="comboxHour_SelectionChanged"     />
                <ComboBox   Name="comboxMinute"  ItemsSource="{Binding Minute}"  Width="100" Margin="5,0,0,0" SelectionChanged="comboxHour_SelectionChanged"    />
                <Button Name="btnGoPaqu" Content="立即爬取接口" Width="140" FontSize="18" Margin="5,0,0,0" Click="Button_Click"></Button>
            </StackPanel>
            <StackPanel Style="{StaticResource StackPanel1}"  >
                <Label Style="{StaticResource Label2}">时间2,时分:</Label>
                <!--<ComboBox  Name="comboxHour"  ItemsSource="{Binding Hour}" DisplayMemberPath="Name" SelectedValuePath="Value" Width="100" />-->
                <ComboBox  Name="comboxHour2"   Width="100" SelectionChanged="comboxHour_SelectionChanged"    />
                <ComboBox   Name="comboxMinute2"  Width="100" Margin="5,0,0,0" SelectionChanged="comboxHour_SelectionChanged"    />
               
                <!--显示是否在工作-->
                <TextBlock Name="lamp" Width="40"  Background="Magenta" Margin="50,0,0,0" DockPanel.Dock="Left" ></TextBlock>
            </StackPanel>
            <StackPanel  Style="{StaticResource StackPanel1}"  >
                <Label Style="{StaticResource Label2}">时间3,时分:</Label>
                <ComboBox  Name="comboxHour3"   Width="100"  SelectionChanged="comboxHour_SelectionChanged"    />
                <ComboBox   Name="comboxMinute3"    Width="100" Margin="5,0,0,0" DockPanel.Dock="Left" SelectionChanged="comboxHour_SelectionChanged"    />
            </StackPanel>
            <StackPanel Style="{StaticResource StackPanel1}"  >
                <Label Style="{StaticResource Label2}">时间4,时分:</Label>
                <ComboBox  Name="comboxHour4"   Width="100"  SelectionChanged="comboxHour_SelectionChanged"    />
                <ComboBox   Name="comboxMinute4"    Width="100"  Margin="5,0,0,0"   SelectionChanged="comboxHour_SelectionChanged"    />
            </StackPanel>
            <DockPanel Style="{StaticResource DockPanel1}">
                <!--<ListView Name="listView" Height="100"/>-->
                <TextBox Name="logMsg" FontSize="14" IsReadOnly="True" Height="300"  TextWrapping="WrapWithOverflow" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto"  />
            </DockPanel>
            <Border BorderBrush="Blue" BorderThickness="1" Margin="0,10,0,0">
                <StackPanel     >
                    <Label Content="发布成功后,甲甲文章信息:"  FontSize="14"></Label>
                    <TextBox Name="txtResult"  IsReadOnly="True"  Height="200" FontSize="14" TextWrapping="Wrap"></TextBox>
                </StackPanel>
            </Border>
    
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs


using CefSharp;
using CefSharp.OffScreen;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml.Linq;

namespace Wpf_CHZC_Img_Identy_ApiDataGet
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
  
            #endregion



            try
            {
                var settings = new CefSettings()
                {
                    CookieableSchemesExcludeDefaults = false,
                    PersistSessionCookies = true,
                    Locale = "zh-CN",
                    UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0"

                };

                //Perform dependency check to make sure all relevant resources are in our output directory.
                Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);

            }
            catch (Exception ex)
            {
                LogHelpter.AddLog("Cef.Initialize初始化异常" + ex.Message, null, "error_Cef.Initialize");
            }

            //自动登陆,获取身份
            //this.Dispatcher.Invoke(new Action(async () =>
            //{
            //    LoginHandle loginHandle = new LoginHandle();
            //    await loginHandle.Login();
            //}));
			
            EventHandler<string> func = (s, e) =>
            {
                ShowMsg(e);
            };

            //订阅消息, 显示
            ApiJsonGetHandle.ShowLog += func;

            ApiJsonGetHandle.DoLogin +=  (s, e) =>
            {
                this.Dispatcher.Invoke(new Action(async  () => {
                    //登录失效,从新登录
                    LoginHandle loginHandle = new LoginHandle();
                    await loginHandle.Login();
                }));         
            };

            //订阅登录消息
            LoginHandle.ShowLog += func;

            //订阅消息,文章发布成功后,显示访问信息
            ApiJsonGetHandle.SetArticleInfo += (s, e) =>
            {
                this.txtResult.Dispatcher.Invoke(new Action(() =>
                {
                    string txtMsg = "更新时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") +
                     System.Environment.NewLine + e;
                    this.txtResult.Text = txtMsg;
                }));

            };
        }


        public List<ConfigNameValue> Hour = new List<ConfigNameValue>();

        public List<string> Minute = new List<string>();

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Hour.Add(new ConfigNameValue() { Name = "请选择", Value = "" });
            for (int i = 0; i < 24; i++)
            {
                string name = i.ToString();
                if (i < 10)
                {
                    name = "0" + i;
                }
                Hour.Add(new ConfigNameValue() { Name = name, Value = name });
            }
            //小时选择
            var hourList = Hour.Select(g => g.Name).ToList();



            //分钟选择
            Minute.Add("请选择");
            for (int i = 0; i < 60; i++)
            {
                if (i < 10)
                {
                    Minute.Add("0" + i);
                }
                else
                {
                    Minute.Add(i.ToString());
                }
            }
            //---------------第一个
            this.comboxHour.ItemsSource = hourList;
            comboxMinute.ItemsSource = Minute;
            this.comboxHour.SelectedIndex = 0;
            comboxMinute.SelectedIndex = 0;

            //---------------第二个
            comboxHour2.ItemsSource = hourList;
            comboxMinute2.ItemsSource = Minute;

            //设置默认选择
            this.comboxHour2.SelectedIndex = 0;
            comboxMinute2.SelectedIndex = 0;

            //---------------第三个
            comboxHour3.ItemsSource = hourList;
            comboxMinute3.ItemsSource = Minute;

            //设置默认选择
            this.comboxHour3.SelectedIndex = 0;
            comboxMinute3.SelectedIndex = 0;

            comboxHour4.ItemsSource = hourList;
            comboxMinute4.ItemsSource = Minute;
            this.comboxHour4.SelectedIndex = 0;
            comboxMinute4.SelectedIndex = 0;

            //listView.Items.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));

            //定时爬取
            var task = new Task(async () =>
            {

                while (true)
                {
                    string time1 = string.Empty;
                    string time2 = string.Empty;
                    string time3 = string.Empty;
                    string time4 = string.Empty;
                    comboxHour.Dispatcher.Invoke(() =>
                    {
                        time1 = comboxHour.SelectedValue + ":" + comboxMinute.SelectedValue + ":00";
                        time2 = comboxHour2.SelectedValue + ":" + comboxMinute2.SelectedValue + ":00";
                        time3 = comboxHour3.SelectedValue + ":" + comboxMinute3.SelectedValue + ":00";
                        time4 = comboxHour4.SelectedValue + ":" + comboxMinute4.SelectedValue + ":00";

                        //ShowMsg("执行时间点:" + time1 + "," + time2 + "," + time3);
                    });

                    string hhmm = DateTime.Now.ToString("HH:mm:ss");
                    if (
                    (!string.IsNullOrWhiteSpace(time1) && hhmm.Equals(time1))
                        || (!string.IsNullOrWhiteSpace(time2) && hhmm.Equals(time2))
                        || (!string.IsNullOrWhiteSpace(time3) && hhmm.Equals(time3))
                        || (!string.IsNullOrWhiteSpace(time4) && hhmm.Equals(time4))
                    )
                    {
                        ShowMsg("命中时间点" + hhmm + ",执行爬取数据...");

                        //到时间点,爬取记录,爬取很成功,推送到;
                        await DoGetHttpJsonDataAndPush();
                    }

                    //指示灯,显示是否在工作              
                    lamp.Dispatcher.InvokeAsync(() =>
                    {
                        if (DateTime.Now.Second % 2 == 0)
                        {
                            lamp.Background = System.Windows.Media.Brushes.LimeGreen;
                        }
                        else
                        {
                            lamp.Background = System.Windows.Media.Brushes.White;
                        }
                    });
                    Thread.Sleep(1000);
                }

            }, creationOptions: TaskCreationOptions.LongRunning);
            task.Start();
 
        }

        /// <summary>
        /// 立即爬取数据
        /// </summary>
        /// <returns></returns>
        private async Task DoGetHttpJsonDataAndPush()
        {
            try
            {


                //到时间点,爬取记录,爬取很成功,推送到;
                var result = await ApiJsonGetHandle.PushToRongMeiTiAsync();
                if (result.Code == 200)
                {
                    txtResult.Dispatcher.InvokeAsync(() =>
                    {
                        //读取历史json
                        string json = ArticleLocalJsonReadFileHandle.ReadArticle();
                        string txtMsg = "更新时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") +
                       System.Environment.NewLine + json;
                        txtResult.Text = txtMsg;
                    });


                    var info = result.Data as ArticleRongmeti;
                    ShowMsg("调用转发服务成功,ArticleId=" + info?.publish_article_id);
                }
            }
            catch (Exception ex)
            {
                var ex1 = ex.InnerException ?? ex;
                string msg = ex1.Message;
                ShowMsg("DoGetHttpJsonDataAndPush异常" + msg);
                LogHelpter.AddLog("DoGetHttpJsonDataAndPush异常" + msg);
            }
        }

        private static StringBuilder stringBuilder = new StringBuilder();

        /// <summary>
        /// 显示消息
        /// </summary>
        /// <param name="msg"></param>
        /// 创建时间:2023-11-20 15:11:17,
        public void ShowMsg(string msg)
        {
            stringBuilder.AppendLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + ">" + msg);

            logMsg.Dispatcher.InvokeAsync(new Action(() =>
            {
                logMsg.Text = stringBuilder.ToString();
                //logMsg.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
                if (!logMsg.IsFocused)
                {
                    logMsg.ScrollToEnd();
                }

            }));

            //清理历史字符串
            if (stringBuilder.Length > 10000000)
            {
                stringBuilder.Remove(0, 200);
            }
        }

        //立即爬取,按钮触发
        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            btnGoPaqu.IsEnabled = false;
            await DoGetHttpJsonDataAndPush();
 
            btnGoPaqu.IsEnabled = true;
        }


        private void comboxHour_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (comboxHour.SelectedValue.Equals("请选择"))
            {
                e.Handled = true;
                return;
            }
            //ShowMsg("选择了" + comboxHour.SelectedValue);
            TimeConfig timeConfig = new TimeConfig()
            {
                Time1 = comboxHour.SelectedValue + ":" + comboxMinute.SelectedValue,
                Time2 = comboxHour2.SelectedValue + ":" + comboxMinute2.SelectedValue,
                Time3 = comboxHour3.SelectedValue + ":" + comboxMinute3.SelectedValue,
                Time4 = comboxHour4.SelectedValue + ":" + comboxMinute4.SelectedValue,
            };
            //保存时间设置
            TimeConfigHandle.WriteTimeConfig(timeConfig);
        }




    }
}

爬取逻辑

using CefSharp.DevTools.Audits;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls.Ribbon.Primitives;
using System.Windows.Documents;

namespace Wpf_CHZC_Img_Identy_ApiDataGet
{
    /// <summary>
    /// api接口获取;XX数据获取
    /// </summary>
    /// 创建时间:2023-11-20 09:09:55,
    public class ApiJsonGetHandle
    {
        /// <summary>
        /// 显示消息
        /// </summary>
        public static event EventHandler<string>? ShowLog;

        /// <summary>
        /// 设置文章信息,到UI 控件展示
        /// </summary>
        public static event EventHandler<string>? SetArticleInfo;

        /// <summary>
        /// 执行登录,
        /// </summary>
        public static event EventHandler DoLogin;


        /// <summary>
        /// 成化总厂,接口数据获取
        /// </summary>
        /// 创建时间:2023-11-20 09:09:55,
        public static async Task<string?> GetApiJsonAsync(string cookieValue, string dateStart, string dateEnd, string deptId)
        {
            try
            {

                HttpClient httpClient = new HttpClient();
                httpClient.Timeout = TimeSpan.FromSeconds(13);

                //httpClient.DefaultRequestHeaders.Add("Content-Type", "application/json");
                httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + cookieValue);

                ShowLog?.Invoke(1, "开始爬取接口数据");

                //{"startDate":"2023-11-17","endDate":"2023-11-17","deptId":"XNeOZRJIHLSibwHOpFBkH3aL49ZEEVQq"}
                //HttpContent httpContent = JsonContent.Create("{\"startDate\":\"" + dateStart + "\",\"endDate\":\"" + dateEnd + "\",\"deptId\":\"" + deptId + "\"}");
                HttpContent httpContent = new StringContent("{\"startDate\":\"" + dateStart + "\",\"endDate\":\"" + dateEnd + "\",\"deptId\":\"" + deptId + "\"}");

                httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json") { CharSet = "utf-8" };

                /*
       http://11.89.104.129:8099/api/system/workPermitScore/riskPublicityPage?pageSize=10&pageNum=1
                 */
                string url = MyConfigReader.GetConfigValue("ay_chzc_fxzy_url");
                var httpResponseMessage = await httpClient.PostAsync(url, httpContent);
                if (!httpResponseMessage.IsSuccessStatusCode)
                {
                    return null;
                }
                string json = await httpResponseMessage.Content.ReadAsStringAsync();
                ShowLog?.Invoke(1, "获取到接口数据" + json);
                //"code":401
                if (json.IndexOf("\"code\":401") >= 0)
                {
                    //登录失效,从新登录
                    DoLogin?.Invoke(1,new EventArgs());
                    //LoginHandle loginHandle = new LoginHandle();
                    //await loginHandle.Login();

                    //等待cookie写入完成
                    await Task.Delay(8 * 1000);
                }

                return json;
            }
            catch (Exception ex)
            {
                ShowLog?.Invoke(1, "获取json数据失败:" + ex.Message);

                LogHelpter.AddLog("获取json数据失败" + ex.ToString(), null, "ApiJsonGetHandle_error");
                return null;
            }
        }

        /// <summary>
        /// 推送数据到甲甲
        /// </summary>
        /// <returns></returns>
        /// 创建时间:2023-11-20 11:14:40,
        public static async Task<ResultPublish> PushToRongMeiTiAsync()
        {
            int count = 1;
            int countRead = 1;
        Again:
            string cookieValue = LoginSuccessCookieHandle.ReadCookieValue();
            if (string.IsNullOrWhiteSpace(cookieValue))
            {
                if (count <= 1)
                {
                    //LoginHandle login = new LoginHandle();
                    //await login.Login();
                    DoLogin?.Invoke(1, new EventArgs());

                    count++;
                    goto Again;
                }
                if (countRead < 20)
                {
                    cookieValue = LoginSuccessCookieHandle.ReadCookieValue();
                    Thread.Sleep(2000);
                    countRead++;
                    goto Again;
                }
                LogHelpter.AddLog("没有获取到身份cookie值", null, "PushToRongMeiTi_error");
                return new ResultPublish() { Code = 500, Msg = "没有获取到身份cookie值" };
            }
            string dateStart = DateTime.Now.ToString("yyyy-MM-dd");
            string deptId_chzc = MyConfigReader.GetConfigValue("deptId_chzc");

            //获取XX 接口数据
            string? json = await GetApiJsonAsync(cookieValue.Trim(), dateStart, dateStart, deptId_chzc);
            if (string.IsNullOrEmpty(json))
            {
                LogHelpter.AddLog("没有数据", "PushToRongMeiTi");
                return new ResultPublish() { Code = 500, Msg = "没获取到数据" };
            }
            if (json.IndexOf("\"code\":401") >= 0)
            {
                goto Again;
            }
            ShowLog?.Invoke(1, "开始推送到甲甲");

            ArticleRongmeti info = new ArticleRongmeti();
            info.Title = "XX风险作业api数据";
            info.HtmlContent = json;
            info.ColumnID = MyConfigReader.GetConfigValue("column_id");
            info.News_type = 1;
            //info.ArticleId = "chzcayxt_fxzy231120";  //DateTime.Now.Ticks.ToString();
            info.ArticleId = MyConfigReader.GetConfigValue("chzc_publish_origin_id");
            info.PublishingStartDate = DateTime.Now;

            LogHelpter.AddLog("接口数据:" + Newtonsoft.Json.JsonConvert.SerializeObject(info), "PushToRongMeiTi_json");

            ResultPublish result;

            //检查文章是否已经发布了?有记录的执行修改接口
            string jsonLocal = ArticleLocalJsonReadFileHandle.ReadArticle();
            if (!string.IsNullOrWhiteSpace(jsonLocal) && jsonLocal.Length > 0)
            {
                //执行修改文章
                var oldInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<RmtResult>(jsonLocal);
                info.RongmetiArticleId = oldInfo.Data.Rongmeiti_article_id;
                info.publish_article_id = oldInfo.Data.Publish_article_id;
                result = await PublishArticelToRongmeti.UpdateArticle(info);
            }
            else
            {
                //推送到甲甲
                //var result = await PublishArticelToRongmeti.PublishArticle(info);
                result = await PublishArticelToRongmeti.PublishArticle(info);
            }

            ShowLog?.Invoke(1, $"甲甲转发系统:{result.Code},Publish_article_id={result.Data},{result.Msg}");

            if (result.Code == 200)
            {
                更新数据到本地json
                //ArticleLocalJsonReadFileHandle.WriteArticleToFile(json);
                long publish_article_id = 0;
                if (result.Msg.Contains("修改"))
                {
                    publish_article_id = info.publish_article_id;
                }
                else
                {
                    var resutlArticle = Newtonsoft.Json.JsonConvert.DeserializeObject<RmtArticleInfo>(result.Data.ToString());

                    publish_article_id = resutlArticle.Publish_article_id;
                }

                //推送成功,需要获取文章在甲甲的信息,比如URL;
                Task.Run(async () =>
                {
                    int index = 1;
                    while (index <= 12)
                    {
                        bool right = await GetArticleInfo(publish_article_id);
                        if (right) break;

                        index++;
                        Thread.Sleep(2 * 1000);
                    }
                });

            }

         //   LogHelpter.AddLog($"调用转发服务接口:状态={result.Code},{result.Msg}", null, "PushToRongMeiTi");

            return result;
        }

        /// <summary>
        /// 获取发布后,文章信息,包含可访问的甲甲文章url
        /// </summary>
        /// <param name="articleId"></param>
        public static async Task<bool> GetArticleInfo(long publish_article_Id)
        {
            HttpClient httpClient = new HttpClient();
            string rmtZhuanFaSeverUrl = PublishArticelToRongmeti.GetRongmeitiPublishArticleUrl();
            rmtZhuanFaSeverUrl = rmtZhuanFaSeverUrl.Replace("PublishArticle", "ArticleInfo");

            string sign = MD5Helpter.MD5Encryptbit32Back16HEX(publish_article_Id + PublishArticelToRongmeti.AppSecret);

            string url = rmtZhuanFaSeverUrl + $"?id={publish_article_Id}&sign={sign}&appid={PublishArticelToRongmeti.AppId}";
            var responseMessage = await httpClient.GetAsync(url);
            if (responseMessage.IsSuccessStatusCode)
            {
                string json = await responseMessage.Content.ReadAsStringAsync();

                //成功的文章,记录文章信息json
                ArticleLocalJsonReadFileHandle.WriteArticleToFile(json);

                //通知ui控件,显示json
                SetArticleInfo?.Invoke(12233, json);
                return true;
            }
            return false;
        }

    }
}

模拟登录

//using CefSharp.Wpf;
using CefSharp;
using CefSharp.OffScreen;
using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Formats.Asn1;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Xml.Linq;

namespace Wpf_CHZC_Img_Identy_ApiDataGet
{
    /// <summary>
    /// 登录模拟
    /// </summary>
    /// 创建时间:2023-11-20 15:34:27 
    public class LoginHandle
    {
        /// <summary>
        /// 登录消息通知
        /// </summary>
        public static event EventHandler<string>? ShowLog;

 
        /// <summary>
        /// 标记是否正在登录?独占登录,同一时间不允许多个登录
        /// </summary>
        static bool loginDoing = false;

       
        /// <summary>
        /// 登录
        /// </summary>
        public async Task Login()
        {
            if (loginDoing)
            {
                return;
            }
            loginDoing = true;
            try
            {
                ShowLog?.Invoke(1, "正在登录...");

                //登录的网页URL,      http://10.45.22.33:8233/#/ 
                string testUrl = "http://10.45.22.33:8233/#/";

                // Create the offscreen Chromium browser.
                var browser = new ChromiumWebBrowser(testUrl)
                {
                    RequestHandler = new MyRequestHandler()
                };
                //browser.Size = new System.Drawing.Size(1920, 20000);

                // 加载完成
                browser.FrameLoadEnd += Browser_FrameLoadEnd;

                //等待内容完成加载
                var response = await browser.WaitForInitialLoadAsync();
                ShowLog?.Invoke(1, "登录页,等待内容完成加载...");
                
            }
            catch (Exception ex)
            {
                loginDoing = false;
                string msg = ex.Message;
                
                ShowLog?.Invoke(1, "登录异常:" + msg);
            }

        }

        private async void Browser_FrameLoadEnd(object? sender, FrameLoadEndEventArgs e)
        {
            var browser = sender as ChromiumWebBrowser;

            int checkImgCount = 1;
        Again_get_imgCode:
            string html = await browser.GetSourceAsync();
            

            ShowLog?.Invoke(1, "处理验证码图片 ");

            //获取验证码图片  base64
            //document.querySelector(".login-code-img").src;
            var imgTask = await browser.GetBrowser().MainFrame.EvaluateScriptAsync("document.querySelector(\".login-code-img\").src;");
            if (!imgTask.Success)
            {
                loginDoing = false;
                ShowLog?.Invoke(1, "验证码图片获取失败 ");
               
                return;
            }

            System.Drawing.Image img = null;
            try
            {
                string base64Img = imgTask.Result.ToString();
                ShowLog?.Invoke(1, "base64Img=" + base64Img);

                base64Img = base64Img.Replace("data:image/gif;base64,", "");
                byte[] bytes = Convert.FromBase64String(base64Img);
                MemoryStream memStream = new MemoryStream(bytes);
                img = System.Drawing.Bitmap.FromStream(memStream);

                ShowLog?.Invoke(1, "验证码图片base64解析成功 ");
            }
            catch (Exception ex)
            {
                loginDoing = false;
                ShowLog?.Invoke(1, "验证码base64读取异常 " + ex.Message);
                
                if (checkImgCount > 20)
                {
                    return;
                }
                checkImgCount++;
                ShowLog?.Invoke(1, "再次去读取验证码url ");
                goto Again_get_imgCode;
                //return;
            }

            //图片保存路径
            string dir = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "imgCode");
            if (!System.IO.Directory.Exists(dir))
            {
                System.IO.Directory.CreateDirectory(dir);
            }
            string fileSavePath = System.IO.Path.Combine(dir, DateTime.UtcNow.Ticks + ".jpg");
            img.Save(fileSavePath);

            //识别验证码图片
            ShowLog?.Invoke(1, "识别验证码图片:" + fileSavePath);
            Identify_codeImg identity_CodeImg = new Identify_codeImg();
            string identifyCode = identity_CodeImg.action(fileSavePath);
           
            int calcValue = 0;/* 计算结果 */
         
            string account = "134064";    /* 登录账号  */
            string password = "an1zan@123";  /* 登录密码  */

            //输入账号            
            var accountJs = await browser.GetBrowser().MainFrame.EvaluateScriptAsync(
                                            @$"var account23 = document.querySelector('input');
                                                account23.value = '{account}';
                                                account23.dispatchEvent(new Event('input'));
                                          ");

            //输入密码
            var passwordJs = await browser.GetBrowser().MainFrame.EvaluateScriptAsync(
                                           @$"var password = document.querySelector(""input[type = 'password']"");
                                                password.value = '{password}';
                                                password.dispatchEvent(new Event('input'));
                                               ");

            //输入验证码
            var vcode78Js = await browser.GetBrowser().MainFrame.EvaluateScriptAsync(
                                         @$"var vcode78 = document.querySelector(""input[placeholder='验证码']"");
                                                vcode78.value = '{calcValue}';
                                                vcode78.dispatchEvent(new Event('input'));
                                     ");

            //点击登录
            var buttonClick = await browser.GetBrowser().MainFrame.EvaluateScriptAsync(
                              "document.querySelector(\"button\").dispatchEvent(new Event(\"click\"));");
            ShowLog?.Invoke(1, "点击登录");
            try
            {
      
                //等待跳转页面
                var home = await browser.WaitForNavigationAsync(timeout: TimeSpan.FromSeconds(20));
                var response5 = await browser.WaitForInitialLoadAsync();
                //string html2 = await browser.GetSourceAsync();

            }
            catch (Exception ex)
            {
                loginDoing = false;
                var ex2 = ex.InnerException ?? ex;
                string msg = ex2.Message;
                 
            }

            var cookieManager = Cef.GetGlobalCookieManager();
            CookieVisitorHandle visitor = new CookieVisitorHandle();
            visitor.OnCookie = cookie =>
            {
                string url = cookie.Domain + cookie.Path;
                

                ShowLog?.Invoke(1, "获取到cookie=" + cookie.Name + ":" + cookie.Value);

                if (cookie.Path == "/" && cookie.Name == "Admin-Token")
                {
                    if (cookie.Value.Length > 0)
                    {
                        loginDoing = false;

                        //保存cookie值
                        LoginSuccessCookieHandle.WriteCookieValueToFile(cookie.Value);
                        

                        ShowLog?.Invoke(1, "登录成功");

                    }
                }

            };

            cookieManager.VisitAllCookies(visitor);
        }


    }
}

拦截请求

using CefSharp;
using CefSharp.Handler;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Wpf_CHZC_Img_Identy_ApiDataGet
{
    /// <summary>
    /// 拦截请求,
    /// </summary>
    /// 创建时间:2023-11-17 14:18:38,xx
    public class MyRequestHandler : RequestHandler
    {
        protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
        {
            //if (request.Url.Contains("user/getInfo"))
            //{
            //    string[] cookie = request.Headers.GetValues("Cookie");
            //}

            LogHelpter.AddLog("GetResourceRequestHandler请求url:" + request.Url, null, "MyRequestHandler");
 
            return base.GetResourceRequestHandler(chromiumWebBrowser, browser, frame, request, isNavigation, isDownload, requestInitiator, ref disableDefaultHandling);
        }


    }
}

Cookie获取 CookieVisitorHandle

using CefSharp;
using System;

namespace Wpf_CHZC_Img_Identy_ApiDataGet
{
    /// <summary>
    /// Cookie获取
    /// </summary>
    /// 创建时间:2023-11-17 15:39:13。作者:xxx
    public class CookieVisitorHandle : ICookieVisitor
    {
        /// <summary>
        /// 处理Cookie,调用者自定义处理实现
        /// </summary>
        public Action<Cookie> OnCookie;

        public void Dispose()
        {
        }

        public bool Visit(Cookie cookie, int count, int total, ref bool deleteCookie)
        {
            OnCookie?.Invoke(cookie);
            return true;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/175712.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ASM字节码操作类库(打开java语言世界通往字节码世界的大门) | 京东云技术团队

前言&#xff1a;授人以鱼不如授人以渔&#xff0c;应用asm的文章有很多&#xff0c;简单demo的也很多&#xff0c;那么ASM都具备哪些能力呢&#xff1f;如何去学习编写ASM代码呢&#xff1f;什么样的情景需要用到ASM呢&#xff1f;让我们带着这些问题阅读这篇文章吧。 这里由…

功率放大器在无线收发系统中的作用

功率放大器在无线收发系统中也扮演着至关重要的角色。无线通信是一种通过电磁波传输信息的技术&#xff0c;它具有便捷、灵活、广覆盖等优势&#xff0c;在现代社会得到了广泛应用。而功率放大器则是无线收发系统中的核心组件之一&#xff0c;主要用于增强信号的功率和距离。下…

paramiko STELNET登陆设备

实验目的&#xff1a; 公司有一台CE12800的设备&#xff0c;管理地址位172.16.1.2&#xff0c;现在需要编写自动化脚本&#xff0c;通过ssh登陆到设备上并进行简单的信息查看。 实验拓扑&#xff1a; 实验步骤&#xff1a; 步骤1&#xff1a;将本地电脑和ensp的设备进行桥接…

振南技术干货集:制冷设备大型IoT监测项目研发纪实(2)

注解目录 1.制冷设备的监测迫在眉睫 1.1 冷食的利润贡献 1.2 冷设监测系统的困难 &#xff08;制冷设备对于便利店为何如何重要&#xff1f;了解一下你所不知道的便利店和新零售行业。关于电力线载波通信的论战。&#xff09; 2、电路设计 2.1 防护电路 2.1.1 强电防护 …

HT5169 单声道D类音频功放 I2S输入

HT5169是一款内置BOOST升压模块的D类音频功率放大器。内置的BOOST升压模块可通过外置电阻调节升压值&#xff0c;即使是锂电池供电&#xff0c;在升压至7.5V&#xff0c;2Ω负载条件下则能连续输出 11W功率。其支持外部设置调节BOOST输出电压。 HT5169是一颗单声道D类音频功放&…

银河麒麟安装Docker

# 配置阿里云 Centos8 镜像源&#xff0c;需要额外的一些依赖&#xff0c;而这些依赖在麒麟官方的源里面是没有的 sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo# 配置阿里云 docker 镜像源 sudo yum-config-manager --add-r…

4.15每日一题(连续函数在有界闭区域上求最大/小值:拉格朗日乘数法、化条件为无条件法)

方法一&#xff1a;拉格朗日乘数法&#xff08;拉格朗日乘数设的方程比较好解的时候使用&#xff09; 方法二&#xff1a;化条件为无条件 &#xff08;拉格朗日乘数设的方程不好解的时候使用&#xff09; &#xff08;1&#xff09;直角坐标方程化条件为无条件法 &#xff08;2…

WCS WMS WES关系

一、定义&#xff1a; 仓库控制系统 &#xff08;WCS&#xff09; 是一种软件应用程序。 WCS用于指导仓库和配送中心&#xff08;DC&#xff09; 内的实时活动。作为仓库/配送中心的“交通警察”&#xff0c;WCS 负责保持一切顺利运行&#xff0c;最大限度地提高物料搬运子系…

CSS实现空心的“尖角”

大家好&#xff0c;我是南宫&#xff0c;来分享一个昨天解决的问题。 我记得之前刷面试题的时候&#xff0c;CSS面试题里面赫然有一题是“如何用CSS实现三角形”&#xff0c;我觉得这个问题确实很经典&#xff0c;我上的前端培训班当初就讲过。 大概思路如下&#xff1a; 先…

hadoop shell操作 hdfs处理文件命令 hdfs上传命令 hadoop fs -put命令hadoop fs相关命令 hadoop(十三)

hadoop fs -help rm 查看rm命令作用 hadoop fs 查看命令 1. 创建文件夹&#xff1a; # hdfs前缀也是可以的。更推荐hadoop hadoop fs -mkdir /sanguo 2.上传至hdfs命令&#xff1a; 作用&#xff1a; 从本地上传hdfs系统 &#xff08;本地文件被剪切走&#xff0c;不存在了&…

技术分享| gcc版本升级到5.2

一、介绍 GCC&#xff08;GNU Compiler Collection&#xff09;是一套广泛使用的开源编译器集合&#xff0c;用于编译多种编程语言&#xff0c;包括C、C、Objective-C、Fortran等。GCC 的不同版本提供了许多新功能、改进和修复&#xff0c;其中包括从 GCC 4.8.5 升级到 GCC 5.…

分享十几个适合新手练习的软件测试项目

说实话&#xff0c;在找项目的过程中&#xff0c;我下载过&#xff08;甚至付费下载过&#xff09;N多个项目、联系过很多项目的作者&#xff0c;但是绝大部分项目&#xff0c;在我看来&#xff0c;并不适合你拿来练习&#xff0c;它们或多或少都存在着“问题”&#xff0c;比如…

AIGC 点亮创作之旅,「重内容」行业也能轻装出发

毋庸置疑&#xff0c;AIGC 的普及成为了内容产业的一束光。 不仅策划们可以从信息挖掘、素材调用、修改编辑等基础文案工作中解放出来&#xff0c;美术也成为 AIGC 的应用强项&#xff0c;基本的加文字、换背景、改尺寸、延展素材等&#xff0c;都能快速解决。 内容创作者们也因…

kafka权限认证 topic权限认证 权限动态认证-亲测成功

kafka权限认证 topic权限认证 权限动态认证-亲测成功 kafka动态认证 自定义认证 安全认证-亲测成功 MacBook Linux安装Kafka Linux解压安装Kafka 介绍 1、Kafka的权限分类 身份认证&#xff08;Authentication&#xff09;&#xff1a;对client 与服务器的连接进行身份认证…

leetcode 240. 搜索二维矩阵 II

2023.11.22 本题最先想到的是暴力法和二分法&#xff0c;暴力法就不写了&#xff0c;写一下二分法的解法&#xff0c;java代码如下&#xff1a; class Solution {public boolean searchMatrix(int[][] matrix, int target) {for(int[] row : matrix){int left 0;int right r…

新能源车将突破2000万辆,汉威科技为电池安全保驾护航

近年来&#xff0c;我国新能源汽车销量持续突破新高。据中汽协数据&#xff0c;1~10月&#xff0c;国内新能源汽车销量达728万辆&#xff0c;同比增长37.8%&#xff0c;市场占有率达到30.4%。随着第四季度车市传统旺季的到来&#xff0c;新能源消费需求将进一步释放&#xff0c…

一文带你快速了解Python史上最快Web框架

文章目录 1. 写在前面2. Sanic框架简介2.1 背景2.2 特征与优势 3. Sanic框架实战3.1. 安装Sanic3.2. Demo案例编写 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&a…

4.2V升多串LED驱动升压6V9V12V恒流点灯

4.2V升多串LED驱动升压6V9V12V恒流点灯 探索WT7012&#xff0c;这款引领潮流的升压转换器&#xff0c;其强大功能将彻底改变您的LED驱动格局。可以轻松驾驭多达7串白光LED&#xff0c;展现出无与伦比的驱动能力。 无论是单节锂电池还是多节锂电池供电产品&#xff0c;宽电压3…

老知识复盘-SQL从提交到执行到底经历了什么 | 京东云技术团队

一、什么是SQL sql(Structured Query Language: 结构化查询语言)是高级的费过程化编程语言,允许用户在高层数据结构上工作, 是一种数据查询和程序设计语言, 也是(ANSI)的一项标准的计算机语言. but… 目前仍然存在着许多不同版本的sql语言,为了与ANSI标准相兼容, 它们必须以相…

特征工程完整指南 - 第二部分

苏米特班迪帕迪亚 照片由Dan Cristian Pădureş在Unsplash上拍摄 一、说明 DATA&#xff0c;通常被称为原油&#xff0c;需要经过加工和清洁才能有效地用于各种用途。正如我们不直接使用来自其来源的石油一样&#xff0c;数据也经过类似的处理以提取其真正价值。 二、特征选…