当前位置:网站首页>WebView2 通过 PuppeteerSharp 实现RPA获取壁纸 (案例版)
WebView2 通过 PuppeteerSharp 实现RPA获取壁纸 (案例版)
2022-08-11 00:17:00 【蓝创精英团队】
此案例是《.Net WebView2 项目,实现 嵌入 WEB 页面 Chromium内核》文的续集。
主要是针对WebView2的一些微软自己封装的不熟悉的API,有一些人已经对 PuppeteerSharp很熟悉了,那么,直接用 PuppeteerSharp的话,那就降低了学习成本,那还是很有必须要的。
之前自己也RPA获取过联盟的高 清 原画,现在就获取下王者的高 清 壁纸。
王者壁纸自动化获取逻辑分析
其实它的逻辑很简单, 就是官网,打开后,在右下角就看到了皮肤页面部分。
这个时候,点击更多,就会打开全部英雄详情的页面。
这个时候,单点任意一个英雄,就会新开一个页面,这个英雄自己的页面,可以看到具体的皮肤信息了。
这里可以看到有6个皮肤,那么,到这里我就可以获取这6个皮肤作为高清王者的皮肤了。
那么,让程序自动化操作,并把这些信息处理保存好,就是我们要做到的事情。
新建一个WPF项目
新建一个 WPF 项目,要添加 Nuget 包
Install-Package Microsoft.Web.WebView2 -Version 1.0.1293.44
Install-Package PuppeteerSharp -Version 7.1.0
Install-Package HtmlAgilityPack -Version 1.11.43
MainWindow.xaml
界面大致样子和布局
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" HorizontalAlignment="Right">
<Label Name = "loginfo" Content="未采集"/>
<Button Name="start" DockPanel.Dock="Right" Width="150" Content="开始采集" Click="start_Click"/>
</StackPanel>
<wpf:WebView2 Name = "webView2"/>
</DockPanel>
右上角一个提示信息,一个采集的按钮,布局很是简单
如何启用 PuppeteerSharp
其实都是基于谷歌的DevTools协议来的,所以,只要WebView2开启了Debugging端口即可。
var result = await CoreWebView2Environment.CreateAsync(null, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cache"),
new CoreWebView2EnvironmentOptions($"--remote-debugging-port={
Port}"));
await webView2.EnsureCoreWebView2Async(result);
通过WebVeiw2的游览器启动参数 : --remote-debugging-port=6666 来开启DevTools协议的支持。
PuppeteerSharpHelper
public class PuppeteerSharpHelper
{
/// <summary>
/// 获取游览器对象
/// </summary>
public static Task<Browser> GetBrowser(int port, int height, int width)
{
return Puppeteer.ConnectAsync(new ConnectOptions {
DefaultViewport = new ViewPortOptions() {
Height = height, Width = width }, BrowserWSEndpoint = WSEndpointResponse.GetWebSocketDebuggerUrl(port) });
}
internal class WSEndpointResponse
{
public string WebSocketDebuggerUrl {
get; set; }
public static string GetWebSocketDebuggerUrl(int port)
{
string data;
using (var client = new HttpClient())
{
data = client.GetStringAsync($"http://127.0.0.1:{
port}/json/version").Result;
}
return JsonConvert.DeserializeObject<WSEndpointResponse>(data).WebSocketDebuggerUrl;
}
}
}
所用到的王者实体信息
public class HeroInfo
{
public string Name {
get; set; }
public string Url {
get; set; }
public string TargetUrl()
{
return $"https://pvp.qq.com/web201605/{
Url}";
}
public List<HeroSkin> HeroSkins {
get; set; }
}
public class HeroSkin
{
public HeroSkin(string name, string url)
{
this.Name = name;
this.Url = "https:" + url;
}
public string Name {
get; set; }
public string Url {
get; set; }
}
RPA的核心代码
private async void start_Click(object sender, RoutedEventArgs e)
{
var herolistPath = await Currentpage.EvaluateExpressionAsync<string>("document.querySelector('body > div.wrapper > div.main > div:nth-child(3) > div.skin_center.fl > div.item_header > a').href");
await Currentpage.GoToAsync(herolistPath, WaitUntilNavigation.DOMContentLoaded);
loginfo.Content = "开始获取内容";
var herolist = await Currentpage.EvaluateExpressionAsync<string>("document.querySelector('body > div.wrapper > div > div > div.herolist-box > div.herolist-content > ul').innerHTML");
var heros = GetHeroInfos(herolist);
loginfo.Content = $"获取全部英雄信息共:{
heros.Count}条";
foreach (var item in heros)
{
await Currentpage.GoToAsync(item.TargetUrl(), WaitUntilNavigation.DOMContentLoaded);
Thread.Sleep(100);
var skins = await Currentpage.EvaluateExpressionAsync<string>("document.querySelector('body > div.wrapper > div.zk-con1.zk-con > div > div > div.pic-pf > ul').innerHTML");
item.HeroSkins = GetHeroSkins(skins);
}
loginfo.Content = "开始下载资源";
var count = 0;
//开始执行下载
foreach (var item in heros)
{
count++;
loginfo.Content = $"资源一共:{
heros.Count}条,正在下载第{
count}条,还剩下:{
heros.Count - count}";
var HearoPath = System.IO.Path.Combine(ImagesPath, item.Name);
if (!System.IO.Directory.Exists(HearoPath))
{
System.IO.Directory.CreateDirectory(HearoPath);
}
foreach (var skin in item.HeroSkins)
{
await WebHelper.DownloadFile(skin.Url, System.IO.Path.Combine(HearoPath, $"{
skin.Name}.jpg"));
}
}
loginfo.Content = "获取完毕,等待查看!";
}
效果如下:
需要点击获取按钮,就会执行自动化获取操作,然后把获取的内容存储到当前项目bin目录images目录下。
下面就是下载完后的效果。

整整齐齐,很完整,都是我喜欢的英雄和买不起的皮肤。
而且,获取到的包含了皮肤的名称
总结
基于WebView2,技术又深一层次的展开,一个好的技术,必定用到合适的场景上才是最合适的。
代码地址
https://github.com/kesshei/WangZheRongYao.git
https://gitee.com/kesshei/WangZheRongYao.git
阅
一键三连呦!,感谢大佬的支持,您的支持就是我的动力!
版权
蓝创精英团队
边栏推荐
- 15. Interceptor - HandlerInterceptor
- Navicat 16-数据库工具
- 详解JDBC的实现与优化(万字详解)
- SQL注入基础
- 从0开始设计JVM ,忘记名词跟上思路一次搞懂
- 力扣每日一题-第52天-387. 字符串中的第一个唯一字符
- Dump file generation, content, and analysis
- electron -autoUpdater 更新
- CF1427F-Boring Card Game【贪心】
- There is no recycle bin for deleted files on the computer desktop, what should I do if the deleted files on the desktop cannot be found in the recycle bin?
猜你喜欢

如何破坏Excel文件,让其显示文件已损坏方法
![[Excel知识技能] 将数值格式数字转换为文本格式](/img/fb/79d6928456f090d47f0fe7a5074979.png)
[Excel知识技能] 将数值格式数字转换为文本格式

Easy-to-use translation plug-in - one-click automatic translation plug-in software

IEEE的论文哪里可以下载?

App regression testing, what are the efficient testing methods?

线上突然查询变慢怎么核查

Mysql. Slow Sql

Why do programming languages have the concept of variable types?

ArcGIS Pro 创建tpk

时间戳转换为日期格式、获取当前时间戳
随机推荐
两个链表的第一个公共节点——LeetCode
13. Content Negotiation
15. 拦截器-HandlerInterceptor
李彦宏拆墙交朋友,大厂“塑料友情”能否帮百度啃下硬骨头?
SQL注入基础
镜头之滤光片---关于日夜两用双通滤光片
【考虫 六级英语】语法课笔记
详解JDBC的实现与优化(万字详解)
EN 12467纤维水泥平板产品—CE认证
"NIO Cup" 2022 Nioke Summer Multi-School Training Camp 4 ADHK Problem Solving
Deep Learning Transformer Architecture Analysis
【mysql】mysql分别按年/月/日/周分组统计数据
两个数组的交集
从0开始设计JVM ,忘记名词跟上思路一次搞懂
YOLOv5的Tricks | 【Trick11】在线模型训练可视化工具wandb(Weights & Biases)
14. Thymeleaf
[Data Visualization] Chart Design Principles
力扣------用栈操作构建数组
2022.8.10-----leetcode.640
Web-based meal ordering system in epidemic quarantine area