假如没有装置能够先装置一下,在.BackgroundJobs层装置PuppeteerSharp:Install-Package PuppeteerSharp
在Jobs文件夹下新建一个PuppeteerTestJob.cs,继承IBackgroundJob,同样是在ExecuteAsync()办法中执行操作。
//PuppeteerTestJob.cs
using System;
using System.Threading.Tasks;
namespace Meowv.Blog.BackgroundJobs.Jobs.PuppeteerTest
{
public class PuppeteerTestJob : IBackgroundJob
{
public async Task ExecuteAsync()
{
throw new NotImplementedException();
}
}
}
运用 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision); 第一次检测到没有阅读器文件会默许帮我们下载 chromium 阅读器。
DownloadAsync(…)能够指定 Chromium 版本,BrowserFetcher.DefaultRevision 下载当前默许最稳定的版本。
然后配置阅读器启动的方式。
using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
Args = new string[] { “–no-sandbox” }
});
感兴味的能够本人看看LaunchOptions有哪些参数,我这里指定了Headless = true 以无头形式运转阅读器,然后加了一个启动参数 “–no-sandbox”。针对Linux环境下,假如是运转在 root 权限下,在启动 Puppeteer 时要添加 “–no-sandbox” 参数,否则 Chromium 会启动失败。
我们翻开一个异步加载的网页,然后获取到页面加载完后的HTML,以我个人博客中的某个单页为例:https://meowv.com/wallpaper 。
//PuppeteerTestJob.cs
using PuppeteerSharp;
using System.Threading.Tasks;
namespace Meowv.Blog.BackgroundJobs.Jobs.PuppeteerTest
{
public class PuppeteerTestJob : IBackgroundJob
{
public async Task ExecuteAsync()
{
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
Args = new string[] { “–no-sandbox” }
});
using var page = await browser.NewPageAsync();
await page.SetViewportAsync(new ViewPortOptions
{
Width = 1920,
Height = 1080
});
var url = “https://meowv.com/wallpaper”;
await page.GoToAsync(url, WaitUntilNavigation.Networkidle0);
var content = await page.GetContentAsync();
}
}
}
page.SetViewportAsync()设置网页预览大小,page.GoToAsync()语法翻开网页,WaitUntilNavigation.Networkidle0等候网页加载终了,运用page.GetContentAsync()获取到HTML。
新建扩展办法,调用这个PuppeteerTestJob的ExecuteAsync()办法,调试看看效果。
1
HTML曾经出来了,此时该干嘛就干嘛就能够了。
第一次运转可能会很慢,由于假如你本地不存在 Chromium 是会去帮我们下载的,由于网络缘由可能会下载的很慢,所以引荐大家手动下载。
能够运用淘宝的源:https://npm.taobao.org/mirrors/chromium-browser-snapshots/ 。
要留意的是,下载完成后的解压的途径不能出错,默许下载地址是在启动目录下面。
Windows:…local-chromium\Win64-706915\chrome-win 、 Linux:…/.local-chromium/Linux-706915/chrome-linux
接下来试试生成PDF和保管图片功用,运用方式也很简单。
await page.PdfAsync(“meowv.pdf”,new PdfOptions { });
await page.ScreenshotAsync(“meowv.png”, new ScreenshotOptions
{
FullPage = true,
Type = ScreenshotType.Png
});
这里只做简单的展现,page.PdfAsync()直接生成PDF文件,同时还有很多办法能够本人调用page.试试,PdfOptions选项中能够设置各种参数。
page.ScreenshotAsync()保管图片,ScreenshotOptions中FullPage能够设置保管图片为全屏形式,图片格式为Png类型。
2
能够看到项目根目录曾经生成了图片和PDF,觉得去试试吧。
接下里来完成发送邮件的功用。
我这里发邮件的账号是用的腾讯企业邮箱,也能够用普通邮箱开通SMTP效劳即可。
在appsettings.json配置收发邮件的账号等信息。
//appsettings.json
“Email”: {
“Host”: “smtp.exmail.qq.com”,
“Port”: 465,
“UseSsl”: true,
“From”: {
“Username”: “[email protected]”,
“Password”: “[Password]”,
“Name”: “MEOWV.COM”,
“Address”: “[email protected]”
},
“To”: [
{
“Name”: “test1”,
“Address”: “[email protected]”
},
{
“Name”: “test2”,
“Address”: “[email protected]”
}
]
}
然后再AppSettings中读取配置的项。
//AppSettings.cs
public static class Email
{
///
/// Host
///
public static string Host => _config["Email:Host"];
///
/// Port
///
public static int Port => Convert.ToInt32(_config["Email:Port"]);
///
/// UseSsl
///
public static bool UseSsl => Convert.ToBoolean(_config["Email:UseSsl"]);
///
/// From
///
public static class From
{
///
/// Username
///
public static string Username => _config["Email:From:Username"];
///
/// Password
///
public static string Password => _config["Email:From:Password"];
///
/// Name
///
public static string Name => _config["Email:From:Name"];
///
/// Address
///
public static string Address => _config["Email:From:Address"];
}
///
/// To
///
public static IDictionary To
{
get
{
var dic = new Dictionary();
var emails = _config.GetSection("Email:To");
foreach (IConfigurationSection section in emails.GetChildren())
{
var name = section["Name"];
var address = section["Address"];
dic.Add(name, address);
}
return dic;
}
}
}
分别引见下每项的含义:
Host:发送邮件效劳器地址。
Port:效劳器地址端口号。
UseSsl:能否运用SSL方式。
From:发件人的账号密码,称号及邮箱地址,普通邮箱地址和账号是相同的。
To:收件人邮箱列表,也包含称号和邮箱地址。
收件人邮箱列表我将其读取为IDictionary
接着在.ToolKits层添加一个EmailHelper.cs,收发邮件我选择了MailKit和MailKit两个库,没有装置的先装置一下,Install-Package MailKit、Install-Package MimeKit。
直接新建一个发送邮件的办法SendAsync(),依照请求将根本的配置信息填进去,然后直接调用即可。
//EmailHelper.cs
using MailKit.Net.Smtp;
using Meowv.Blog.Domain.Configurations;
using MimeKit;
using System.Linq;
using System.Threading.Tasks;
namespace Meowv.Blog.ToolKits.Helper
{
public static class EmailHelper
{
///
/// 发送Email
///
///
///
public static async Task SendAsync(MimeMessage message)
{
if (!message.From.Any())
{
message.From.Add(new MailboxAddress(AppSettings.Email.From.Name, AppSettings.Email.From.Address));
}
if (!message.To.Any())
{
var address = AppSettings.Email.To.Select(x => new MailboxAddress(x.Key, x.Value));
message.To.AddRange(address);
}
using var client = new SmtpClient
{
ServerCertificateValidationCallback = (s, c, h, e) => true
};
client.AuthenticationMechanisms.Remove("XOAUTH2");
await client.ConnectAsync(AppSettings.Email.Host, AppSettings.Email.Port, AppSettings.Email.UseSsl);
await client.AuthenticateAsync(AppSettings.Email.From.Username, AppSettings.Email.From.Password);
await client.SendAsync(message);
await client.DisconnectAsync(true);
}
}
}
SendAsync(…)接纳一个参数MimeMessage对象,这样就完成了一个通用的发邮件办法,接着我们去需求发邮件的中央结构MimeMessage,调用SendAsync()。
//WallpaperJob.cs
…
// 发送Email
var message = new MimeMessage
{
Subject = “【定时任务】壁纸数据抓取任务推送”,
Body = new BodyBuilder
{
HtmlBody = $“本次抓取到{wallpapers.Count()}条数据,时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss}”
}.ToMessageBody()
};
await EmailHelper.SendAsync(message);
…
//HotNewsJob.cs
…
// 发送Email
var message = new MimeMessage
{
Subject = “【定时任务】每日热点数据抓取任务推送”,
Body = new BodyBuilder
{
HtmlBody = $“本次抓取到{hotNews.Count()}条数据,时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss}”
}.ToMessageBody()
};
await EmailHelper.SendAsync(message);
…
分别在两个爬虫脚本中添加发送Email,MimeMessage中设置了邮件主题Subject,正文Body,最后调用await EmailHelper.SendAsync(message)执行发送邮件操作。
编译运转执行两个定时任务,看看能否收到邮件提示。
3
胜利了,邮箱收到了两条提示。
还有一种比拟特殊的用法,也引见一下,假如想要发送带图片的邮件怎样操作呢?留意不是附件,是将图片内嵌在邮箱中。
普通常规都是有邮件模板的,将图片的详细地址插入到img标签中,这就不说了,这里选择另外一种方式。以前面添加的PuppeteerTestJob为例,正好我们生成了一张图片的。将这种图片以邮件的方式发进来。
public class PuppeteerTestJob : IBackgroundJob
{
public async Task ExecuteAsync()
{
var path = Path.Combine(Path.GetTempPath(), “meowv.png”);
...
await page.ScreenshotAsync(path, new ScreenshotOptions
{
FullPage = true,
Type = ScreenshotType.Png
});
// 发送带图片的Email
var builder = new BodyBuilder();
var image = builder.LinkedResources.Add(path);
image.ContentId = MimeUtils.GenerateMessageId();
builder.HtmlBody = "当前时间:{0}.".FormatWith(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), image.ContentId);
var message = new MimeMessage
{
Subject = "【定时任务】每日热点数据抓取任务推送",
Body = builder.ToMessageBody()
};
await EmailHelper.SendAsync(message);
}
}
先肯定我们生成图片的途径 path ,将图片生成Message-Id,然后赋值给ContentId,给模板中图片标签cid赋上值在调用发送邮件办法即可。