c# 通过webView2模拟登陆小红书网页版,执行关键字搜索,以及解决X-s,X-t,X-S-Common签名验证【2023年5月8日】

一、搜索接口及原理
1、搜索接口

url=https://edith.xiaohongshu.com/api/sns/web/v1/search/notes

2、数据

  var data={"keyword": "",        //搜索关键字:比如:风景视频"page": 1,              //返回第几页数据,1表示返回第一页数据;"page_size": 20,     //20表示一页数据有多少个笔记(视频)"search_id": "2blciviwfc1cdapvnknmj",        //搜索id,根据当前时间生成的唯一字符串;"sort": "general",                                         //排序方式:general 普通排序;"note_type": 0                                            //笔记类型:0表示:视频;};

3、请求头:

headers = {'authority':"edith.xiaohongshu.com",'method':"post",'Content-Type':"application/json;charset=utf8",'accept':"application/json, text/plain, */*",'accept-encoding':"gzip, deflate, br",'accept-language':"zh-CN,zh;q=0.9","cache-control":"no-cache","origin":"https://www.xiaohongshu.com","pragma":"no-cache","sec-ch-ua":"\"Not_A Brand\";v=\"99\", \"Google Chrome\";v=\"109\", \"Chromium\";v=\"109\"","sec-ch-ua-mobile":"?0","sec-ch-ua-platform":"\"Windows\"","sec-fetch-dest":"empty","sec-fetch-mode":"cors","sec-fetch-site":"same-site",'cookie':"a1=186d30820a4m09cb6glhxe1aqks2olv1l97ow1gun50000408881;  web_session=040069b3b3f6625dade26f8d1d364b44f72187;  ",'referer':"https://www.xiaohongshu.com","X-t":1683343307335,"X-s":"O6MKZYwvOYsLZBFisgqUZ61KsYF+OY1lsl1WZYZBsjM3",'X-S-Common':"2UQAPsHC+aIjqArjwjHjNsQhPsHCH0rjNsQhPaHCH0P1PjhIHjIj2eHjwjQgynEDJ74AHjIj2ePjwjQhyoPTqBPT49pjHjIj2ecjwjHUN0P1PaHVHdWMH0ijP/W98ePIweHIG/zTPeS0G08dJBYh8/bYqnTAPfRV40bVw/464Abd4nhMPeZIPecIweWhPjHVHdW9H0il+0WUw/Z9PeHlw/HlNsQh+UHCHDRd8rQOyd+P/MSLpAbk8o8AypzenfkAaAZUprql87+knDQlyMkxwnSyn/LAHjIj2eWjwjQQPAYUaBzdq9k6qB4Q4fpA8b878FSet9RQzLlTcSiM8/+n4MYP8F8LagY/P9Ql4FpUzfpS2BcI8nT1GFbC/L88JdbFyrSiafprwLMra7pFLDDAa7+8J7QgabmFz7Qjp0mcwp4fanD68p40+fp8qgzELLbILrDA+9p3JpHlLLI3+LSk+d+DJfRAyfRL+gSl4bYlqg48qDQlJFShtUTozBD6qM8FyFShPo+h4g4U+obFyLS3qd4QyaRAy9+0PFSe/B8QPFRSPopFJeHIzbkA/epSzb+t8nkn4AmQynpS2b87/sTc4BRUqgziLBMt8/8VzURQ4DzranYlpB4n4FRtqgzMagYbGMk/89pn4gcEag898p8n4bkQy9lNanVhqfEm+d+8pgbn2juM8nkn4ok6LApAL9+Up7kD+np/p9+cagWM8Lzc4rkQzLES8opFJBQCzrpwwL4oagY68pzM49l1J/+S2BzbLrS3pFRQyLYTqgPhzrSezor3zS86anS0ynpc4epQcMki+rQwqFzIa9phqgzma/+mq9kd+7+gGAFRHjIj2eDjwjFl+echPeLFPeDANsQhP/Zjw0rFKc==",'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
}

cookie中的
a1客户端标识,参与X-S-Common签名;web_session登陆会话标识,登陆小红书时会产生此字段,大概1个月有效。
X-t,X-s必须的,由data和url签名产生;X-S-Common必须,由a1,X-t,X-s,MINI_BROSWER_INFO_KEY共同签名产生。

4、具备以上数据后,向服务器发送post请求。

var result = winning.getPostResultEx(url, data_json, headers);

如果参数错误,将返回:

{"code":-1,"success":false}

如果未登陆或web_session失效,将返回未登陆提示;
如果请求成功,将返回第一页(或某一页)(一页20个笔记)json数据:

{"msg":"成功","data":{"has_more":true,"items":[{"model_type":"note","note_card":{"cover":{"height":1706,"width":1280,"url":"https://sns-img-qc.xhscdn.com/1000g0081jf9ote2ao04g5o8kppjg8f48774fb60","trace_id":"1000g0081jf9ote2ao04g5o8kppjg8f48774fb60","file_id":"1000g0081jf9ote2ao04g5o8kppjg8f48774fb60"},"type":"normal","display_title":"美女多多","user":{"nick_name":"雄","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/632952c77cccf41054bf74ec.jpg?imageView2/2/w/80/format/jpg","user_id":"6114ce670000000001003c88","nickname":"雄"},"interact_info":{"liked":false,"liked_count":"1805"}},"id":"6374df81000000001c036084"},{"id":"64195495000000001301092f","model_type":"note","note_card":{"type":"normal","user":{"avatar":"https://sns-avatar-qc.xhscdn.com/avatar/640142a9d27b886b440aea46.jpg?imageView2/2/w/80/format/jpg","user_id":"5cb9cc050000000017030ea4","nickname":"私拍女神","nick_name":"私拍女神"},"interact_info":{"liked":false,"liked_count":"311"},"cover":{"height":1646,"width":1234,"url":"https://sns-img-qc.xhscdn.com/1000g00827hn8oi4fm0005n5ppg2lu3l4q54q030","trace_id":"1000g00827hn8oi4fm0005n5ppg2lu3l4q54q030","file_id":"1000g00827hn8oi4fm0005n5ppg2lu3l4q54q030"}}},{"id":"6432dffc0000000012030dbf","model_type":"note","note_card":{"type":"normal","display_title":"18岁🌸还拿不下你?","user":{"nick_name":"一粒甜豆","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/642e6a60a61cee6d85ad3ec5.jpg?imageView2/2/w/80/format/jpg","user_id":"63082e80000000001501da4b","nickname":"一粒甜豆"},"interact_info":{"liked":false,"liked_count":"14965"},"cover":{"trace_id":"1000g0082algar80h40605oo85q05bmibn1pdc48","file_id":"1000g0082algar80h40605oo85q05bmibn1pdc48","height":1706,"width":1280,"url":"https://sns-img-qc.xhscdn.com/1000g0082algar80h40605oo85q05bmibn1pdc48"}}},{"note_card":{"interact_info":{"liked":false,"liked_count":"368"},"cover":{"file_id":"1000g0082cah7sh4gu0005od9do18d59mjp9nm30","height":1760,"width":1320,"url":"https://sns-img-qc.xhscdn.com/1000g0082cah7sh4gu0005od9do18d59mjp9nm30","trace_id":"1000g0082cah7sh4gu0005od9do18d59mjp9nm30"},"type":"normal","display_title":"海滩 | 粉色女孩","user":{"nick_name":"AI小影","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/6453b3f6fe6243cd283e30b0.jpg?imageView2/2/w/80/format/jpg","user_id":"61a96e020000000021029536","nickname":"AI小影"}},"id":"6440733d0000000027011028","model_type":"note"},{"id":"63d69298000000001d022f88","model_type":"note","note_card":{"interact_info":{"liked":false,"liked_count":"1681"},"cover":{"height":1920,"width":1440,"url":"https://sns-img-qc.xhscdn.com/1000g0081vcuhmp8es0005o7bmt885c21irp600o","trace_id":"1000g0081vcuhmp8es0005o7bmt885c21irp600o","file_id":"1000g0081vcuhmp8es0005o7bmt885c21irp600o"},"type":"normal","display_title":"爱烫头的40岁阿姨","user":{"nick_name":"四季奶青milk","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/6354c63051daefab555b06cd.jpg?imageView2/2/w/80/format/jpg","user_id":"60ebb750000000002002b041","nickname":"四季奶青milk"}}},{"id":"63491ee00000000006029200","model_type":"note","note_card":{"type":"normal","display_title":"美女素材","user":{"user_id":"6231c1150000000010005b32","nickname":"素材分享","nick_name":"素材分享","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/6373751ea5559e15b5803c3b.jpg?imageView2/2/w/80/format/jpg"},"interact_info":{"liked":false,"liked_count":"734"},"cover":{"width":1080,"url":"https://sns-img-qc.xhscdn.com/0302ae01ktx0duoo7ci010zhr7edmyyg2g","trace_id":"0302ae01ktx0duoo7ci010zhr7edmyyg2g","file_id":"0302ae01ktx0duoo7ci010zhr7edmyyg2g","height":1439}}},{"id":"63bd3627000000001f023037","model_type":"note","note_card":{"type":"normal","display_title":"美女图片","user":{"nickname":"疏玲玲🌸","nick_name":"疏玲玲🌸","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/53ba1722242c3e9344db7b0fc2e1005f.jpg?imageView2/2/w/80/format/jpg","user_id":"629d81f0000000002102ae28"},"interact_info":{"liked":false,"liked_count":"211"},"cover":{"file_id":"1000g0081s9s5nimeq05g5oktg7o8dbh8lujuqqg","height":1706,"width":1280,"url":"https://sns-img-qc.xhscdn.com/1000g0081s9s5nimeq05g5oktg7o8dbh8lujuqqg","trace_id":"1000g0081s9s5nimeq05g5oktg7o8dbh8lujuqqg"}}},{"id":"643367d1000000000800d696","model_type":"note","note_card":{"type":"video","user":{"nick_name":"W丽人青蓝W","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/64254adc4af4649956a01daf.jpg?imageView2/2/w/80/format/jpg","user_id":"63e5b3b5000000002702b06b","nickname":"W丽人青蓝W"},"interact_info":{"liked":false,"liked_count":"295"},"cover":{"trace_id":"1000g0082ani1ulgh00305ov5meqptc3b8j2ango","file_id":"1000g0082ani1ulgh00305ov5meqptc3b8j2ango","height":1000,"width":750,"url":"https://sns-img-qc.xhscdn.com/1000g0082ani1ulgh00305ov5meqptc3b8j2ango"}}},{"id":"642fe63b0000000013033795","model_type":"note","note_card":{"cover":{"trace_id":"1000g0082a9sckp2go05g5nsald6081vg02qt9g0","file_id":"1000g0082a9sckp2go05g5nsald6081vg02qt9g0","height":2560,"width":1920,"url":"https://sns-img-qc.xhscdn.com/1000g0082a9sckp2go05g5nsald6081vg02qt9g0"},"type":"video","display_title":"双倍快乐呀","user":{"avatar":"https://sns-avatar-qc.xhscdn.com/avatar/62b6d0693c746fe743dd31de.jpg?imageView2/2/w/80/format/jpg","user_id":"5f8aab4c00000000010007f0","nickname":"特效小哥灰豆","nick_name":"特效小哥灰豆"},"interact_info":{"liked":false,"liked_count":"2588"}}},{"id":"62d96e1c000000001200f212","model_type":"note","note_card":{"user":{"nick_name":"宋琳琳","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/603d00834b428e2d0816097b.jpg?imageView2/2/w/80/format/jpg","user_id":"603cb94a0000000001005a5a","nickname":"宋琳琳"},"interact_info":{"liked":false,"liked_count":"11048"},"cover":{"width":720,"url":"https://sns-img-qc.xhscdn.com/01027l01kohqj14olei011dwfsn1j30qxg","trace_id":"01027l01kohqj14olei011dwfsn1j30qxg","file_id":"01027l01kohqj14olei011dwfsn1j30qxg","height":961},"type":"video","display_title":"迷迷糊糊发个视频!"}},{"note_card":{"user":{"nick_name":"华籍美鱼","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/613cf784cdb961c1162ad2dd.jpg?imageView2/2/w/80/format/jpg","user_id":"5a3735774eacab0d3461e3ac","nickname":"华籍美鱼"},"interact_info":{"liked":false,"liked_count":"5218"},"cover":{"file_id":"030338016i01k7cvelo010zr9980v4zf9o","height":1440,"width":1080,"url":"https://sns-img-qc.xhscdn.com/030338016i01k7cvelo010zr9980v4zf9o","trace_id":"030338016i01k7cvelo010zr9980v4zf9o"},"type":"video","display_title":"☀️喜欢阳光"},"id":"64084a230000000013013647","model_type":"note"},{"note_card":{"user":{"nick_name":"居居","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/644bd7f61300c5cf9d3786e1.jpg?imageView2/2/w/80/format/jpg","user_id":"5f602bc70000000001004977","nickname":"居居"},"interact_info":{"liked":false,"liked_count":"10314"},"cover":{"trace_id":"1000g00827dh7psifo0005nr05f3g8ibnim0droo","file_id":"1000g00827dh7psifo0005nr05f3g8ibnim0droo","height":1440,"width":1080,"url":"https://sns-img-qc.xhscdn.com/1000g00827dh7psifo0005nr05f3g8ibnim0droo"},"type":"video","display_title":"好纯欲!"},"id":"641842140000000014025707","model_type":"note"},{"id":"640da05a0000000027000ded","model_type":"note","note_card":{"type":"normal","user":{"nick_name":"心弦","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/64128a90fc6d6dfb889f9caa.jpg?imageView2/2/w/80/format/jpg","user_id":"634290d70000000018029c84","nickname":"心弦"},"interact_info":{"liked":false,"liked_count":"467"},"cover":{"file_id":"1000g00826408ra6fm05g5oq2i3bm5744cmkaqsg","height":1706,"width":1280,"url":"https://sns-img-qc.xhscdn.com/1000g00826408ra6fm05g5oq2i3bm5744cmkaqsg","trace_id":"1000g00826408ra6fm05g5oq2i3bm5744cmkaqsg"}}},{"id":"64092a94000000001203ffab","model_type":"note","note_card":{"type":"normal","display_title":"清冷系美女","user":{"nick_name":"泡芙不芙","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/63cbba9cf49cc7b05d2f1b3f.jpg?imageView2/2/w/80/format/jpg","user_id":"615e8d45000000001f038367","nickname":"泡芙不芙"},"interact_info":{"liked":false,"liked_count":"7567"},"cover":{"file_id":"03033901krmp1p0mqg7010ij29dcem4gli","height":1706,"width":1280,"url":"https://sns-img-qc.xhscdn.com/03033901krmp1p0mqg7010ij29dcem4gli","trace_id":"03033901krmp1p0mqg7010ij29dcem4gli"}}},{"id":"6441c5440000000013009e24","model_type":"note","note_card":{"interact_info":{"liked":false,"liked_count":"48"},"cover":{"file_id":"1000g0082cfm9ivkh806g5okqirjmsguqdduudlo","height":2560,"width":1920,"url":"https://sns-img-qc.xhscdn.com/1000g0082cfm9ivkh806g5okqirjmsguqdduudlo","trace_id":"1000g0082cfm9ivkh806g5okqirjmsguqdduudlo"},"type":"video","display_title":"清纯美少女","user":{"avatar":"https://sns-avatar-qc.xhscdn.com/avatar/629a96e7000000001b0243da.jpg?imageView2/2/w/80/format/jpg","user_id":"629a96e7000000001b0243da","nickname":"心心相印","nick_name":"心心相印"}}},{"note_card":{"type":"video","user":{"nickname":"小红薯柯柯","nick_name":"小红薯柯柯","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/63dd18b7627a7faf54860ec5.jpg?imageView2/2/w/80/format/jpg","user_id":"63dd12140000000026006855"},"interact_info":{"liked_count":"29","liked":false},"cover":{"file_id":"1000g008207ot5kafi0605out28a9gq2ltnesej0","height":960,"width":720,"url":"https://sns-img-qc.xhscdn.com/1000g008207ot5kafi0605out28a9gq2ltnesej0","trace_id":"1000g008207ot5kafi0605out28a9gq2ltnesej0"}},"id":"63dd72b7000000000d015817","model_type":"note"},{"model_type":"note","note_card":{"interact_info":{"liked":false,"liked_count":"360"},"cover":{"file_id":"1000g00828n5ivcofe06g481srpi2rpg0kuh5gk0","height":2560,"width":1920,"url":"https://sns-img-qc.xhscdn.com/1000g00828n5ivcofe06g481srpi2rpg0kuh5gk0","trace_id":"1000g00828n5ivcofe06g481srpi2rpg0kuh5gk0"},"type":"video","user":{"nick_name":"似梦飞花","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/62cedd038aee919605303931.jpg?imageView2/2/w/80/format/jpg","user_id":"5713642daed758612a88e600","nickname":"似梦飞花"}},"id":"6422eaba0000000012030de9"},{"id":"642bc2dc000000001203f040","model_type":"note","note_card":{"interact_info":{"liked_count":"479","liked":false},"cover":{"height":1797,"width":1348,"url":"https://sns-img-qc.xhscdn.com/1000g00829pn3jkqh000040ci7c3bgd5fb89p5o8","trace_id":"1000g00829pn3jkqh000040ci7c3bgd5fb89p5o8","file_id":"1000g00829pn3jkqh000040ci7c3bgd5fb89p5o8"},"type":"normal","display_title":"这都拿不下你?这也太显身材了好辣妹","user":{"nick_name":"Yyyyi","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/626e51259759af6e5b3d89e1.jpg?imageView2/2/w/80/format/jpg","user_id":"551fc6b89c5a6e5a0f3d34af","nickname":"Yyyyi"}}},{"model_type":"note","note_card":{"user":{"nick_name":"天嘉✨","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/63dcb264cfead81aea1bce25.jpg?imageView2/2/w/80/format/jpg","user_id":"6333b029000000001501e7d6","nickname":"天嘉✨"},"interact_info":{"liked":false,"liked_count":"2253"},"cover":{"trace_id":"03033o01kwpjei1pgba010xx08u0ybcsrp","file_id":"03033o01kwpjei1pgba010xx08u0ybcsrp","height":769,"width":576,"url":"https://sns-img-qc.xhscdn.com/03033o01kwpjei1pgba010xx08u0ybcsrp"},"type":"video","display_title":"是谁在偷看美女睡觉"},"id":"641d56080000000011010302"},{"id":"642c0a3d0000000011013313","model_type":"note","note_card":{"display_title":"简简单单的大美女穿搭!超显身材的一套~~","user":{"nick_name":"安野萘缨","avatar":"https://sns-avatar-qc.xhscdn.com/avatar/60965f6b231383d089ecfc3d.jpg?imageView2/2/w/80/format/jpg","user_id":"5d3ff38d00000000120302cc","nickname":"安野萘缨"},"interact_info":{"liked":false,"liked_count":"1316"},"cover":{"file_id":"1000g00829qpv7hsgq0005n9vue6km0mctkmsa9g","height":1440,"width":1080,"url":"https://sns-img-qc.xhscdn.com/1000g00829qpv7hsgq0005n9vue6km0mctkmsa9g","trace_id":"1000g00829qpv7hsgq0005n9vue6km0mctkmsa9g"},"type":"video"}}]},"code":0,"success":true}

json数据中的"has_more":true表示还有下一页,可再次请求第二页数据....直到"has_more":false

5、X-s,X-t签名方法:

function sign_s(data)
{
var args = '/api/sns/web/v1/search/notes';
var t=JSON.parse(data);
var o = _sign(args, t);
//需要X-s,X-t签名算法的+v:metabycf
return o;
}

可见,X-s,X-t对搜索接口url及post数据data签名,返回结果如下:

{ X-t: 1683156321085, X-s: 'sYZksj1GsgspOjTb1BVks6FLslOU121KsBTK0YTGOgc3'}

6、X-S-Common签名方法:

  var A={"s0": 5,"s1": "","x0": "1","x1": "3.2.0","x2": "Windows","x3": "xhs-pc-web","x4": "2.3.1","x5": "186d30820a4m09cb6glhxe1aqks2olv1l97ow1gun50000408882","x6": 1683159186565,"x7": "O6MKZYwvOYsLZBFisgqUZ61KsYF+OY1lsl1WZYZBsjM3","x8": "I38rHdgsjopgIvesdVwgIC+oIELmBZ5e3VwXLgFTIxS3bqwErFeexd0ekncAzMFYnqthIhJeSnMDKutRI3KsYorWHPtGrbV0P9WfIi/eWc6eYqtyQApPI37ekmR1QL+5Ii6sdnosjoT5yqtXqqwYrBqoIx++GDi/sVtkIx0sxuwr4qtiIkrwIi/skcc3ICLfI3Oe0utl20DZsL5eDSJejVw0IieexVwL+PtorqthPmoeTYG/IvDDIhqTgVwOJqtuIxEcZSgeVut9IvveVVtZIklKIk8rnA6sYUqVz/5ejVtzoS5sScrWzd5eSWcPIx5eDqt/IEKeDPtIrmWhNnLGIxoeTuwlnm3exdEPIkWOIiHmqs8DICDq+FVoIiciePt5ICZh4BNsDpKexqtAI3Asjg7sWc==","x9": -1675349166,"x10": 6};

其中:
s0,s1,x0,x1,x2,x3,x4固定;
x5即是cookie中的a1字段;
x6既是X-t;
x7既是X-s;
x8既是MINI_BROSWER_INFO_KEY客户端浏览器信息标识;
x9为:x6,x7,x8签名产生:

  var e=A["x6"]+A["x7"]+A["x8"];var mcr1=mcr(e);var res=mcr1(e);A['x9']=res;

X-S-Common为A字符串的base64编码:

  var str = JSON.stringify(A);var base = new BASE64();var comm= base.encode(str);//需要X-S-Common签名算法的+v:metabycf

二、c# WebView2简介


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

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

三、通过c# WebView2获取cookie信息的方法:


private Dictionary mCookies = new Dictionary();//保存Cookie到字典中/// /// WebView2异步获取cookie/// /// 与cookie关联的域名private async void getCookie(string url){List cookieList = await webView.CoreWebView2.CookieManager.GetCookiesAsync(url);mCookies.Clear();for (int i = 0; i < cookieList.Count; ++i){CoreWebView2Cookie cookie = webView.CoreWebView2.CookieManager.CreateCookieWithSystemNetCookie(cookieList[i].ToSystemNetCookie());mCookies.Add(cookie.Name, cookie.Value);}}/// /// 提取cookie中的一个字段;/// /// 域名/// 关键字,如:web_session/// 延时(没用到)/// 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;}

四、WebView2中C#和JavaScript代码互操作

1.需要创建一个ScriptHost对象,并注册到WebView2中:

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

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

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

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

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

五、与javascript交互

using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
using System;
using System.Collections.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 System.Net.Http;
using System.Net.Http.Headers;namespace XhsVideo
{/// /// 网页调用C#方法,需要完整源码的+v:metabycf/// [ClassInterface(ClassInterfaceType.AutoDual)][ComVisible(true)]public class ScriptHost{private WebView2 webView;private Dictionary mCookies = new Dictionary();//保存Cookie到字典中private string mUrl;public static ScriptHost scriptHost = null;private ScriptHost(WebView2 webView){scriptHost = this;this.webView = webView;//注册事件侦听,加载页面完成时,获取cookie;this.webView.NavigationCompleted += new System.EventHandler(this.webView_NavigationCompleted);//webView初始化完成后注册与JavaScript交互this.webView.CoreWebView2InitializationCompleted += new System.EventHandler(this.webView_CoreWebView2InitializationCompleted);}public static ScriptHost GetScriptHost(WebView2 webView){if (scriptHost == null) scriptHost = new ScriptHost(webView);return scriptHost;}/// /// 日志记录(JavaScript前端调用/// /// JavaScript前端信息public void log(string message){Log.i(message);//记录到文本文件中//MessageBox.Show(message);}/// /// 提取cookie中的一个字段;/// /// 域名/// 关键字,如:web_session/// 延时(没用到)/// 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=040069b3b3f6625dade26f8d1d364b44f72187";return cookies;}return null;}/// /// WebView2异步获取cookie/// /// 与cookie关联的域名private async void getCookie(string url){List cookieList = await webView.CoreWebView2.CookieManager.GetCookiesAsync(url);mCookies.Clear();for (int i = 0; i < cookieList.Count; ++i){CoreWebView2Cookie cookie = webView.CoreWebView2.CookieManager.CreateCookieWithSystemNetCookie(cookieList[i].ToSystemNetCookie());mCookies.Add(cookie.Name, cookie.Value);}}public string getCookie(){string cookies = "";foreach (var cookie in mCookies){cookies += cookie.Key + "=" + cookie.Value + ";";}return cookies;}/// /// 记录由JavaScript返回的信息/// /// public void getJsResult(string text){fMainForm.GetFMainForm().syncContext.Send(fMainForm.GetFMainForm().SetTextSafePost, text);//Post 将信息发送到窗体显示}//---------------------------------------------------------socket--------------------------------------------------------------------------------/// /// 重定向链接,该方法由JavaScript调用;/// /// /// /// /// public string getRedirectedUrl(string url, string domain, string ua){return NetHelper.getRedirectedUrl(url, domain, ua);}/// /// 提交post请求,该方法由JavaScript调用;/// /// /// /// /// public string getPostResultEx(string url, string args, string headers){log(url);log(args);log(headers);return NetHelper.getPostResult(url, args, headers);}//-----------------------------------------------------------事件---------------------------------------------------------------------------/// /// 加载完页面时,获取cookie/// /// /// private void webView_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e){string url = webView.Source.Host.ToString();url = "https://" + url;getCookie(url);}/// /// CoreWebView2初始化完成/// /// /// private void webView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e){//注册winning,winasync脚本c#互操作webView.CoreWebView2.AddHostObjectToScript("scriptHost", scriptHost);//注册全局变量winning 同步操作;winasync:异步操作;webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("var winasync= window.chrome.webview.hostObjects.scriptHost;");webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("var winning= window.chrome.webview.hostObjects.sync.scriptHost;");}}
}


六、网络访问组件


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using System.Windows.Forms;namespace XhsVideo
{/// /// 网络访问组件/// internal class NetHelper{#region 文件下载/// /// 下载文件/// /// 文件下载地址/// 本地保存路径+名称/// 下载回调(总长度,已下载,进度)/// /// public static async Task DownloadFileAsync(string url, string savePath, Action downloadCallBack = null){try{downloadCallBack?.Invoke($"文件【{url}】开始下载!");HttpResponseMessage response = null;using (HttpClient client = new HttpClient())response = await client.GetAsync(url);if (response == null){downloadCallBack?.Invoke("文件获取失败");return;}var total = response.Content.Headers.ContentLength ?? 0;var stream = await response.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);//.ToZeroif ((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/// /// 异步下载文件/// /// /// public static async void downloadfileAsync(string url,string filename){using (var web = new WebClient()){await web.DownloadFileTaskAsync(url, filename);}}/// /// 地址重定向/// /// 原地址/// 域名/// userAgent/// 重定向后的地址public static string getRedirectedUrl(string url, string domain, string ua){var str = getRedirectedUrl_T(url);return str.Result;}/// /// 异步地址重定向/// /// /// private static async Task getRedirectedUrl_T(string url){try{var handler = new HttpClientHandler(){AllowAutoRedirect = false};var client = new HttpClient(handler);var response = await client.GetAsync(url).ConfigureAwait(continueOnCapturedContext: false);int statuscode = (int)response.StatusCode;if (statuscode == 307){string location = response.Headers.Location.ToString();return location;}if (statuscode == 302){string location = response.Headers.Location.ToString();return location;}else{return "";}}catch (Exception e){System.Diagnostics.Debug.WriteLine("getRedirectedUrl_T:" + e.ToString());return "";}}//---------------------------------------------------------------post---------------------------------------------------------------------/// /// Post访问/// /// 访问地址/// 数据/// HTTP头/// 返回服务器JSON数据public static string getPostResult(string url, string args, string headers){var str = getPostResult_T(url, args, headers);return str.Result;}/// /// 异步post调用/// /// /// /// /// private static async Task 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 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());///console.write(e.ToString());return "";}}/// /// 字符串解析为字典数据/// /// 以回车换行符分割的字符串/// 字典数据private static Dictionary ParseToDictionary(string str){Dictionary result = new Dictionary();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 -------------------------------------------------------------------/// /// 获取服务器端的HTML代码/// /// /// public static string getHtmlCode(string url){var str = getHtmlCode_T(url);return str.Result;}/// /// 异步获取服务器端的HTML代码/// /// /// public static async Task 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());///console.write(e.ToString());Log.i(e.ToString());return "";}}}
}

七、使用方法:

    private void btnSearch_Click(object sender, EventArgs e){//string keyword = "风景视频";   搜索关键字string keyword = tbUrl.Text.Trim();//string cookie = scriptHost.getCookie();   string jscode =  Config.jscode;     //javaScript代码webView.CoreWebView2.ExecuteScriptAsync(jscode);   //运行js代码}//js返回信息(该方法由js调用,需要js文件的+v:metabycfpublic void getJsResult(string text){fMainForm.GetFMainForm().syncContext.Send(fMainForm.GetFMainForm().SetTextSafePost, text);//Post 将信息发送到窗体显示}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部