您现在的位置是:首页 > 电脑 > 

c# 通过webView2模拟登陆小红书网页版,解析无水印视频图片,以及解决X-s,X-t签名验证【202年4月29日】

2025-07-19 06:32:29
一、c# WebView2简介   1.一开始使用WebBrowser,因为WebBrowser控件使用的是ie内核,经过修改注册表切换为Edge内核后, 发现Edge内核版本较低,加载一些视频网站提示“浏览器版本过低“,”视频无法加载“。 2.WebBrowser内核版本与WebView2比较 WebBrowser内核

一、c# WebView2简介
  1.一开始使用WebBrowser,因为WebBrowser控件使用的是ie内核,经过修改注册表切换为Edge内核后,
发现Edge内核版本较低,加载一些视频网站提示“浏览器版本过低“,”视频无法加载“。

2.WebBrowser内核版本与WebView2比较

WebBrowser内核版本:
内核版本 (Version) Edge 18.9200 兼容 WebKit 57.6  Chrome 70 
UserAgent: Mozilla/5.0 (Windows T 6.2; WOW64) AppleWebKit/57.6 (KHTML, like Gecko) Chrome/70.0.58.102 Safari/57.6 Edge/18.9200

当前Edge内核版本:
内核版本 (Version)    WebKit 57.6  Chrome 111.0.0.0
UserAgent: Mozilla/5.0 (Windows T 10.0; Win64; x64) AppleWebKit/57.6 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/57.6 Edg/111.0.1661.54

WebView2内核版本:
内核版本 (Version)    WebKit 57.6  Chrome 111.0.0.0
UserAgent:Mozilla/5.0 (Windows T 10.0; Win64; x64) AppleWebKit/57.6 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/57.6 Edg/111.0.1661.51

可见,WebView2内核版本跟Edge一样,能顺利打开视频网站。WebBrowser内核版本过低。

WebView2加载视频网站

.WebView2概述
  Microsoft Edge WebView2 控件允许在本机应用中嵌入 web 技术(HTML、CSS 以及 JavaScript)。 WebView2 控件使用 Microsoft Edge 作为绘制引擎,以在本机应用中显示 web 内容。
虽说无法跨平台,但是在windows应用下做为原浏览器控件替代品还是不错的。

4.安装webview2
   打开uGet,搜索WebView2,安装之后,可以看到左侧就有了webview2控件,可以直接拖到窗体内。

二、问题分析
1、关于登陆会话的问题
网页端必须打开小红书网站。小红书打开后,在浏览器Cookie里,有一个字段:
web_session=040069bbf6625dade26f8d1d64b44f72186
这是记录登陆会话信息的。请求时headers中需要x-s、x-t,cookie中需要有web_session。
经测试,这个web_session会在浏览器保存一段时间,具体多久还有待验证(B站也有个类似的session,是一个月)。其它字段无关紧要。
不使用WebView2打开网站的话,需要到网站申请web_session,这里WebView2已经替我们弄好了。
通过c# WebView2获取cookie信息的方法:

private Dictionary<string, string> mCookies = new Dictionary<string, string>();//保存Cookie到字典中

/// <summary>
        /// WebView2异步获取cookie
        /// </summary>
        /// <param name=url>与cookie关联的域名</param>
        private async void getCookie(string url)
        {
            List<CoreWebView2Cookie> cookieList = await webView.CoreWebView2.CookieManager.GetCookiesAsync(url);
            mCookies.Clear();
            for (int i = 0; i < cookieList.Count; i)
            {
                CoreWebView2Cookie cookie = webView.CoreWebView2.CookieManager.CreateCookieWithSystemetCookie(cookieList[i].ToSystemetCookie());
                mCookies.Add(cookie.ame, cookie.Value);
            }

        }

        /// <summary>
        /// 提取cookie中的一个字段;
        /// </summary>
        /// <param name=url>域名</param>
        /// <param name=key>关键字,如:web_session</param>
        /// <param name=t>延时(没用到)</param>
        /// <returns></returns>
        public string getCookieEx(string url, string key, int t)
        {
            getCookie(url);
            if (mCookies.ContainsKey(key))
            {
                string cookies = ;
                foreach (var cookie in mCookies)
                {
                    cookies = cookie.Key  =  cookie.Value  ;;
                }
                cookies = key  =  mCookies[key];
                return cookies;
            }


            return null;
        }

2.笔记信息接口

目前笔记信息接口: /api/sns/web/v1/feed
请求时headers中需要x-s、x-t,cookie中需要有web_session。

.X-S
定位方法很多,可以全局搜 X-s 。往上可以发现该段为 sign 方法,function sign(e, t) {}

全部复制到本地,然后根据报错把缺的方法和环境补一下,比如a0_0x4dee00、a0_0x5c27、a0_0x54e等方法,

然后把常用的navigator、location、document、window加上就好了。

该过程中根据具体错误再调试分析, 比如sign方法的 case 6,修改为var vr = window 、在case 7中可以手动修改为 dr = ur[ sYMU ]
这里已经拿到了function sign(e, t) {}的JavaScript版,需要的v:byc652

三.解析原理及流程

  1、获取小红书笔记分享链接
Meta发布了一篇小红书笔记,快来看吧! 😆 95mtho0hHhZLd1q 😆 http://xhslink/AKXMyp,复制本条信息,打开【小红书】App查看精彩内容!
  2、执行url重定向得到带来note_id的新链接
https://www.xiaohongshu/discovery/item/640e99c00000000140259d?app_platform=android&amp;app_version=7.8.0&amp;share_from_user_hidden=true&amp;type=video&amp;xhare=CopyLink&amp;appuid=640d1628000000001400dc4d&amp;apptime=1682740972
  、解析出note_id
note_id=640e99c00000000140259d
  4、调用JavaScript function sign(e, t) 签名得到X-s,X-t
X-t: 1682742221056
X-s: Ogsb02Zv0gUJO2w6OB4UOjTl1g9CsBTOj9W0gsK1g1

  5、发送post请求:
   (1)数据:

var args = 	{\source_note_id\:\	  note_id  	\}	;


  (2)请求头(不会的v:byc652):

//JavaScript代码:
var headers = 	X-t: 	  o[	X-t	]  	\r\nX-s: 	  o[	X-s	]  	\r\nContent-Type: application/json;charset=UTF-8\r\nReferer: https://www.xiaohongshu/\r\nCookie: 	  cookie; 


  ()服务器接口:

//JavaScript代码:
var api_url = 	https://edith.xiaohongshu/api/sns/web/v1/feed	;


  (4)发送post:

//JavaScript代码:
var data = winning.getPostResult(api_url, args, headers);


  (5)得到笔记信息数据(json):

{msg:成功,data:{cursor_score:,items:[{id:640e99c00000000140259d,model_type:note,note_card:{at_user_list:[],last_update_time:168092712000,title:幻昼#治愈系风景,desc:,user:{user_id:62c7b52a0000000000fdb4,nickname:Meta,avatar:https://sns-avatar-qc.xhscdn/avatar/62c7de801ab526ecfbf1777.jpg},interact_info:{share_count:1,followed:false,liked:false,liked_count:,collected:false,collected_count:2,comment_count:0},image_list:[{file_id:4e8ce0b1-ba6f-8bf-646b-bf8fea8941f,height:1280,width:720,url:https://sns-img-hw.xhscdn/4e8ce0b1-ba6f-8bf-646b-bf8fea8941f,trace_id:217/0/01e40e94079052e00100001875f0f462_0.jpg}],tag_list:[],time:168092712000,ip_location:云南,note_id:640e99c00000000140259d,share_info:{un_share:false},type:video,video:{media:{video_id:162876686865518,video:{drm_type:0,stream_types:[259],biz_name:110,biz_id:28040285671196925,duration:257,md5:5bb406b78ab014d2114784bc147f10,hdr_type:0},stream:{h265:[],av1:[],h264:[{audio_duration:250729,master_url:http://sns-video-hw.xhscdn/stream/110/259/01e40e99c7922a2010700875f169774_,vmaf:-1,stream_desc:WM_X264_MP4,duration:256800,size:6860844,fps:0,psnr:0,ssim:0,quality_type:HD,height:1280,avg_bitrate:2171,default_stream:0,width:720,video_duration:256800,audio_bitrate:6405,audio_channels:2,backup_urls:[http://sns-video-bd.xhscdn/stream/110/259/01e40e99c7922a2010700875f169774_,http://sns-video-qc.xhscdn/stream/110/259/01e40e99c7922a2010700875f169774_?sign=6c5ffdf48d9c842405bbea5fa61e7&t=644e8f54,http://sns-video-al.xhscdn/stream/110/259/01e40e99c7922a2010700875f169774_],stream_type:259,format:mp4,volume:0,video_codec:h264,hdr_type:0,rotate:0,video_bitrate:206804,audio_codec:aac,weight:62}]}},image:{thumbnail_fileid:110/0/01e40e99c7922a200100001875f111ff_0.webp},capa:{duration:256},cumer:{origin_video_key:spectrum/1000g2f02adqphsqh20005om7mkl0vvdklvh95l8}}}}],current_time:16827447282},code:0,success:true}


  6、解析笔记信息数据(json):
  如果data.items[i].note_= video 说明该笔记为视频内容;
  如果data.items[i].note_= normal 说明该笔记为图文内容;
  7、一张图看懂无水印视频、无水印封面所在位置:
  PHOTO_HOST= https://sns-img-hw.xhscdn/ ;  //无水印封面服务器
  VIDEO_HOST= http://sns-video-bd.xhscdn/ ;  //无水印视频服务器

 

四、WebView2中C#和JavaScript代码互操作
 1.需要创建一个ScriptHost对象,并注册到WebView2中:

    /// <summary>
    /// 网页调用C#方法
    /// </summary>
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class ScriptHost

2.在WebView2初始化完成事件中注册ScriptHost对象

        /// <summary>
        /// CoreWebView2初始化完成
        /// </summary>
        /// <param name=sender></param>
        /// <param name=e></param>

        private void webView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            //注册winning,winasync脚本c#互操作
            webView.CoreWebView2.AddHostObjectToScript(scriptHost, scriptHost);
            //注册全局变量winning 同步操作;winasync:异步操作;
            webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(var winasync= webview.hostObjects.scriptHost;);
            webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(var winning= webview.hostObjects.sync.scriptHost;);
        }

.ScriptHost中暴露的公共方法,都可以在前端JavaScript中调用。

        /// <summary>
        /// 日志记录(JavaScript前端调用
        /// </summary>
        /// <param name=message>JavaScript前端信息</param>
        public void log(string message)
        {
            Log.i(message);//记录到文本文件中
            //MessageBox.Show(message);
        }
..............................................
winning.log(data);//JavaScript端调用(同步调用);

五、下载封面及视频


using System;
using System.Collecti.Generic;
using System.Linq;
using Configuration;
using System.Text;
using System.Threading.Tasks;

namespace XhsVideo
{
    /// <summary>
    /// 下载视频
    /// </summary>
    internal class VideoDown
    {
        public int id { get; set; }
        public VideoInfo video { get; set; }
        public string savedir { get; set; }
        public string msg { get; set; }
        public bool success { get; set; }
        public string headers { get; set; }
        public VideoDown(int id,VideoInfo video,string savdir,string headers=null) {
            this.id = id;
            this.video = video;
            this.savedir = savdir;
            if (System.IO.Directory.Exists(savdir)) System.IO.Directory.CreateDirectory(savdir);
            this.headers = headers;
        }
        public void process()
        {
            string filename = MakeValidFileame( ,);  //去除文件名中的非法字符
            string videoname = savedir  \\  filename  .mp4;
            string covername = savedir  \\  filename  .webp;
            if (System.IO.File.Exists(covername)) System.IO.File.Delete(covername);
            if (System.IO.File.Exists(videoname)) System.IO.File.Delete(videoname);
            Log.i(videoname);
            Log.i(covername);
            //etHelper.downloadfileAsync(video.videoUrl, videoname);
            etHelper.downloadfileAsync(, covername);
            etHelper.DownloadFileAsync(video.videoUrl, videoname, showProgress);//显示下载视频的进度
        }






        /**
            * @param text: 原始串
            * @param replacement: 要替换的字符串
        */
        public static string MakeValidFileame(string text, string replacement = _)
        {
            StringBuilder str = new StringBuilder();
            var invalidFileameChars = System.IO.Path.GetInvalidFileameChars();
            foreach (var c in text)
            {
                if (invalidFileameChars.Contains(c))
                {
                    str.Append(replacement ?? );
                }
                else
                {
                    str.Append(c);
                }
            }

            return str.ToString();
        }
        /// <summary>
        /// 下载视频的进度回调函数
        /// </summary>
        /// <param name=msg>下载进度信息</param>
        public void showProgress(string msg)
        {
             = msg;
            Log.i(msg);
            fMainForm.GetFMainForm().syncContext.Send(fMainForm.GetFMainForm().SetTextSafePost, this);//Post 将信息发送到窗体显示

        }

    }


    /// <summary>
    /// 视频信息类,由:标题,封面地址,视频地址组成。
    /// </summary>

    public class VideoInfo
    {
        public string title { get; set; }
        public string coverUrl { get; set; }
        public string videoUrl { get; set; }
        public VideoInfo(string title,string coverUrl,string videoUrl)
        {
             = title;
             = coverUrl;
            this.videoUrl = videoUrl;
        }
    }
}

六、日志记录


using System;
using System.Collecti.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XhsVideo
{
    /// <summary>
    /// 日志记录 到文本文件
    /// </summary>
    internal class Log
    {
        private static  Log log;
        private static string logame;
        private Log(string filename) {
            logame = filename;
        }
        public static Log GetLog(string filename)
        {
            if (log == null) { log = new Log(filename); }
            return log;
        }
        public static Log GetLog()
        {
            return log;
        }
        public static void i(string msg)
        {
            string now = ToString();
            string[] text = new string[2];
            text[0] = now;
            text[1] = msg;
            try
            {
                using (StreamWriter sw = new StreamWriter(logame,true,Encoding.UTF8))
                {
                    foreach (string s in text)
                    {
                        sw.WriteLine(s);

                    }
                    sw.Close();
                }
                
            }
            catch (Exception e)
            {
                //Cole.WriteLine(Exception:   e.Message);
            }
            finally
            {
                //Cole.WriteLine(Executing finally block.);
            }
        }
    }
}

七、网络访问组件


using System;
using System.Collecti.Generic;
using System.Linq;
using Http.Headers;
using Http;
using System.Text;
using System.Threading.Tasks;
using ;
using System.IO;
using System.Windows.Forms;

namespace XhsVideo
{
    /// <summary>
    /// 网络访问组件
    /// </summary>
    internal class etHelper
    {

        #region 文件下载
        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name=url>文件下载地址</param>
        /// <param name=savePath>本地保存路径名称</param>
        /// <param name=downloadCallBack>下载回调(总长度,已下载,进度)</param>
        /// <returns></returns>
        /// <exception cref=Exception></exception>
        public static async Task DownloadFileAsync(string url, string savePath, Action<string> downloadCallBack = null)
        {
            try
            {
                downloadCallBack?.Invoke($文件【{url}】开始下载!);
                HttpRespeMessage respe = null;
                using (HttpClient client = new HttpClient())
                    respe = await client.GetAsync(url);
                if (respe == null)
                {
                    downloadCallBack?.Invoke(文件获取失败);
                    return;
                }
                var total = respe.Content.Headers.ContentLength ?? 0;
                var stream = await respe.Content.ReadAsStreamAsync();
                var file = new FileInfo(savePath);
                using (var fileStream = file.Create())
                using (stream)
                {
                    if (downloadCallBack == null)
                    {
                        await stream.CopyToAsync(fileStream);
                        downloadCallBack?.Invoke($文件【{url}】下载完成!);
                    }
                    else
                    {
                        byte[] buffer = new byte[1024];
                        long readLength = 0;
                        int length;
                        double temp = 0;
                        string msg = ;
                        while ((length = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
                        {
                            // 写入到文件
                            fileStream.Write(buffer, 0, length);

                            //更新进度
                            readLength = length;
                            double progress = Math.Round((double)readLength / total * 100, 2, MidpointRounding.AwayFromZero);//.ToZero

                            if ((progress % 1) == 0 && (progress % 1) != temp)
                            { 
                                msg = $总大小:【{total}】,已下载:【{readLength}】,进度:【{progress}】;
                                downloadCallBack?.Invoke(msg);
                            }
                            temp = progress % 1;
                            //下载完毕立刻关闭释放文件流
                            if (total == readLength && progress == 100)
                            {
                                fileStream.Close();
                                fileStream.Dispose();
                                msg = $总大小:【{total}】,已下载:【{readLength}】,进度:【{progress}】下载完成。;
                                downloadCallBack?.Invoke(msg);
                            }


                        }
                    }
                }
            }
            catch (Exception ex)
            {
                downloadCallBack?.Invoke($下载文件失败:{ex.Message}!);
            }
        }
        #endregion




        /// <summary>
        /// 异步下载文件
        /// </summary>
        /// <param name=url></param>
        /// <param name=filename></param>
        public static async void downloadfileAsync(string url,string filename)
        {
            using (var web = new WebClient())
            {
                await web.DownloadFileTaskAsync(url, filename);
            }
        }
      
        /// <summary>
        /// 地址重定向
        /// </summary>
        /// <param name=url>原地址</param>
        /// <param name=domain>域名</param>
        /// <param name=ua>userAgent</param>
        /// <returns>重定向后的地址</returns>
        public static string getRedirectedUrl(string url, string domain, string ua)
        {
            var str = getRedirectedUrl_T(url);
            return str.Result;
        }
        /// <summary>
        /// 异步地址重定向
        /// </summary>
        /// <param name=url></param>
        /// <returns></returns>
        private static async Task<string> getRedirectedUrl_T(string url)
        {
            try
            {
                var handler = new HttpClientHandler()
                {
                    AllowAutoRedirect = false
                };
                var client = new HttpClient(handler);

                var respe = await client.GetAsync(url).ConfigureAwait(continueOnCapturedContext: false);
                int statuscode = (int)respe.StatusCode;
                if (statuscode == 07)
                {
                    string location = respe.Headers.Location.ToString();
                    return location;
                }
                if (statuscode == 02)
                {
                    string location = respe.Headers.Location.ToString();
                    return location;
                }
                else
                {
                    return ;
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(getRedirectedUrl_T:  e.ToString());
                return ;
            }
        }
        //---------------------------------------------------------------post---------------------------------------------------------------------
        /// <summary>
        /// Post访问
        /// </summary>
        /// <param name=url>访问地址</param>
        /// <param name=args>数据</param>
        /// <param name=headers>HTTP头</param>
        /// <returns>返回服务器JSO数据</returns>
        public static string getPostResult(string url, string args, string headers)
        {
            var str = getPostResult_T(url, args, headers);
            return str.Result;
        }
        /// <summary>
        /// 异步post调用
        /// </summary>
        /// <param name=url></param>
        /// <param name=args></param>
        /// <param name=headers></param>
        /// <returns></returns>
        private static async Task<string> getPostResult_T(string url, string args, string headers)
        {
            try
            {
                var handler = new HttpClientHandler() { UseCookies = false };
                var client = new HttpClient(handler);// { BaseAddress = baseAddress };
                client.Timeout = TimeSpan.FromSeconds(20);
                var message = new HttpRequestMessage(HttpMethod.Post, url);
                message.Content = new StringContent(args);
                message.Content.Headers.ContentType = new MediaTypeHeaderValue(application/json);
                //message.Headers;
                Dictionary<string, string> dictionary = ParseToDictionary(headers);
                foreach (var pair in dictionary)
                {
                    if (pair.Key.Equals(content-type)) continue;
                    if (pair.Key.Equals(Content-Type)) continue;
                    message.Headers.Add(pair.Key, pair.Value);
                }

                var result = await client.SendAsync(message).ConfigureAwait(continueOnCapturedContext: false);
                result.EnsureSuccessStatusCode();
                return await result.Content.ReadAsStringAsync();
            }
            catch (Exception e)
            {
                //EventLog.GetEventLogs(e.ToString);
                System.Diagnostics.Debug.WriteLine(getPostResultEx_T:  e.ToString());
                ///cole.write(e.ToString());
                return ;
            }
        }
        
        /// <summary>
        /// 字符串解析为字典数据
        /// </summary>
        /// <param name=str>以回车换行符分割的字符串</param>
        /// <returns>字典数据</returns>
        private static Dictionary<string, string> ParseToDictionary(string str)
        {
            Dictionary<string, string> result = new Dictionary<string, string>();
            string str1 = str;
            int i = str1.IndexOf(\r\n);
            int j = 0;
            while (i > 0)
            {
                string str2 = str1.Substring(0, i);
                j = str2.IndexOf(:);
                if (j > 0)
                {
                    string str21 = str2.Substring(0, j);
                    string str22 = str2.Substring(j  1);
                    result.Add(str21, str22);
                }
                str1 = str1.Substring(i  2);
                i = str1.IndexOf(\r\n);
            }
            j = str1.IndexOf(:);
            if (j > 0)
            {
                string str21 = str1.Substring(0, j);
                string str22 = str1.Substring(j  1);
                result.Add(str21, str22);
            }
            return result;
        }
        //-------------------------------------------------------------------GET -------------------------------------------------------------------
        /// <summary>
        /// 获取服务器端的HTML代码
        /// </summary>
        /// <param name=url></param>
        /// <returns></returns>
        public static string getHtmlCode(string url)
        {
            var str = getHtmlCode_T(url);
            return str.Result;
        }
        /// <summary>
        /// 异步获取服务器端的HTML代码
        /// </summary>
        /// <param name=url></param>
        /// <returns></returns>
        public static async Task<string> getHtmlCode_T(string url)
        {
            try
            {
                var http = new HttpClient();
                http.Timeout = TimeSpan.FromSeconds(10);
                var result = await http.GetStringAsync(url).ConfigureAwait(continueOnCapturedContext: false);
                return result;
            }
            catch (Exception e)
            {
                //EventLog.GetEventLogs(e.ToString);
                System.Diagnostics.Debug.WriteLine(错误信息在这儿:  e.ToString());
                ///cole.write(e.ToString());
                Log.i(e.ToString());
                return ;
            }
        }

    }
}

八、ScriptHost与JavaScript交互(主要流程):

using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
using System;
using System.Collecti.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Threading;
using System.Security.Policy;
using Http;
using Http.Headers;

namespace XhsVideo
{
    /// <summary>
    /// 网页调用C#方法
    /// </summary>
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class ScriptHost
    {
        
        private WebView2 webView;
        private Dictionary<string, string> mCookies = new Dictionary<string, string>();//保存Cookie到字典中
        private string mUrl;
        public static ScriptHost scriptHost = null;
        private ScriptHost(WebView2 webView)
        {
            scriptHost = this;
            this.webView = webView;
            //注册事件侦听,加载页面完成时,获取cookie;
            this.webView.avigationCompleted = new System.EventHandler<Microsoft.Web.WebView2.Core.CoreWebView2avigationCompletedEventArgs>(this.webView_avigationCompleted);
            //webView初始化完成后注册与JavaScript交互
            this.webView.CoreWebView2InitializationCompleted = new System.EventHandler<Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs>(this.webView_CoreWebView2InitializationCompleted);
        }
        public static ScriptHost GetScriptHost(WebView2 webView)
        {
            if (scriptHost == null) scriptHost = new ScriptHost(webView);
            return scriptHost;
        }
        /// <summary>
        /// 日志记录(JavaScript前端调用
        /// </summary>
        /// <param name=message>JavaScript前端信息</param>
        public void log(string message)
        {
            Log.i(message);//记录到文本文件中
            //MessageBox.Show(message);
        }
        /// <summary>
        /// 提取cookie中的一个字段;
        /// </summary>
        /// <param name=url>域名</param>
        /// <param name=key>关键字,如:web_session</param>
        /// <param name=t>延时(没用到)</param>
        /// <returns></returns>
        public string getCookieEx(string url, string key, int t)
        {
            getCookie(url);
            if (mCookies.ContainsKey(key))
            {
                string cookies = ;
                foreach (var cookie in mCookies)
                {
                    cookies = cookie.Key  =  cookie.Value  ;;
                }
                cookies = key  =  mCookies[key];
                //cookies = web_session=040069bbf6625dade26f8d1d64b44f72186;
                return cookies;
            }


            return null;
        }
        /// <summary>
        /// WebView2异步获取cookie
        /// </summary>
        /// <param name=url>与cookie关联的域名</param>
        private async void getCookie(string url)
        {
            List<CoreWebView2Cookie> cookieList = await webView.CoreWebView2.CookieManager.GetCookiesAsync(url);
            mCookies.Clear();
            for (int i = 0; i < cookieList.Count; i)
            {
                CoreWebView2Cookie cookie = webView.CoreWebView2.CookieManager.CreateCookieWithSystemetCookie(cookieList[i].ToSystemetCookie());
                mCookies.Add(cookie.ame, cookie.Value);
            }

        }
        /// <summary>
        /// 解析并下载由JavaScript返回的信息
        /// </summary>
        /// <param name=text></param>
        public void getJsResult(string text)
        {
            Log.i(text);
            string temp = text;
            string[] ss = text.Split(	,	);
            string title = ;
            string coverUrl = ;
            string videoUrl = ;
            string origin_video_key = ;
            string trace_id = ;
            int id = 0;
            foreach (string s in ss)
            {
                string[] dd = s.Split(	=	);
                if (dd.Length == 2)
                {
                    if (dd[0].Equals(title)) title = dd[1];
                    if (dd[0].Equals(cover_url)) coverUrl = dd[1];
                    if (dd[0].Equals(video_url)) videoUrl = dd[1];
                    if (dd[0].Equals(origin_video_key)) origin_video_key = dd[1];
                    if (dd[0].Equals(trace_id)) trace_id = dd[1];
                    if (dd[0].Equals(id)) id = int.Parse(dd[1]);
                }
           
            }
            videoUrl = http://sns-video-hw.xhscdn/  origin_video_key;//无水印视频
            coverUrl = https://sns-img-qc.xhscdn/  trace_id;//无水印封面
            VideoInfo video = new VideoInfo(title, coverUrl, videoUrl);//创建视频信息对象
            VideoDown videodown=new VideoDown(id, video, Config.savedir);//创建视频下载对象
            videodown.process();//执行下载


        }
        //---------------------------------------------------------socket--------------------------------------------------------------------------------
        /// <summary>
        /// 重定向链接,该方法由JavaScript调用;
        /// </summary>
        /// <param name=url></param>
        /// <param name=domain></param>
        /// <param name=ua></param>
        /// <returns></returns>
        public string getRedirectedUrl(string url, string domain, string ua)
        {
            return etHelper.getRedirectedUrl(url, domain, ua);
        }
        /// <summary>
        /// 提交post请求,该方法由JavaScript调用;
        /// </summary>
        /// <param name=url></param>
        /// <param name=args></param>
        /// <param name=headers></param>
        /// <returns></returns>
        public string getPostResultEx(string url, string args, string headers)
        {
            return etHelper.getPostResult(url, args, headers);
        }
        //-----------------------------------------------------------事件---------------------------------------------------------------------------
        /// <summary>
        /// 加载完页面时,获取cookie
        /// </summary>
        /// <param name=sender></param>
        /// <param name=e></param>
        private void webView_avigationCompleted(object sender, CoreWebView2avigationCompletedEventArgs e)
        {

            string url = webView.Source.Host.ToString();
            url = https://  url;
            getCookie(url);
        }
        /// <summary>
        /// CoreWebView2初始化完成
        /// </summary>
        /// <param name=sender></param>
        /// <param name=e></param>

        private void webView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            //注册winning,winasync脚本c#互操作
            webView.CoreWebView2.AddHostObjectToScript(scriptHost, scriptHost);
            //注册全局变量winning 同步操作;winasync:异步操作;
            webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(var winasync= webview.hostObjects.scriptHost;);
            webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(var winning= webview.hostObjects.sync.scriptHost;);
        }
    }
}

因为涉及的技术知识点太多了,后续继续完善下载无水印图文。


                                         (未完待续)

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/diannao/213181.html

相关标签:无
上传时间: 2023-05-10 07:07:48
留言与评论(共有 11 条评论)
本站网友 原地跑
16分钟前 发表
h264
本站网友 友谊租房
11分钟前 发表
经测试,这个web_session会在浏览器保存一段时间,具体多久还有待验证(B站也有个类似的session,是一个月)
本站网友 让往事随风
15分钟前 发表
0}
本站网友 贴吧表情包
11分钟前 发表
                                         (未完待续)
本站网友 床上蹲着生孩子
0秒前 发表
videoname); etHelper.downloadfileAsync(
本站网友 qq好友列表
23分钟前 发表
.X-S 定位方法很多,可以全局搜 X-s
本站网友 q币有什么用
0秒前 发表
string headers) { try { var handler = new HttpClientHandler() { UseCookies = false }; var client = new HttpClient(handler);// { BaseAddress = baseAddress }; client.Timeout = TimeSpan.FromSeconds(20); var message = new HttpRequestMessage(HttpMethod.Post
本站网友 信阳二手房
6分钟前 发表
args
本站网友 梦见生女孩
10分钟前 发表
[]
本站网友 牧龙原墅
4分钟前 发表
volume