使用 PuppeteerSharp 基于 headless browser 执行 js 脚本
Intro
最近想要做一些自动化讲 markdown 保存到微信公众号草稿,微信公众号文章草稿不支持直接设置 markdown 内容需要转成 html,一直用的 markdown-nice 来做 markdown 到 html 的微信公众号排版,并且自己做了私有部署,于是尝试使用基于 markdown nice 来做 markdown 转 html,markdown-nice 是一个纯前端的 React 项目,没有 API 可以直接转,于是尝试使用 puppeteer 来执行 js 来转换 markdown 到 html
Puppeteer
Puppeteer 是一个 Node.js 库,提供了一个高级 API 来控制无头 Chrome 或 Chromium 浏览器。它可以用于自动化浏览器操作,如生成网页截图、抓取网页内容、测试网页应用程序等。
Puppeteer 的主要特点包括:
-
无头浏览器:默认情况下,Puppeteer 在无头模式下运行,这意味着它不会显示用户界面,可以在后台执行任务,适合自动化和服务器环境。 -
网页抓取:Puppeteer 可以轻松地抓取网页数据,解析内容,提取信息。 -
自动化测试:可以用来编写和执行端到端(E2E)测试,模拟用户操作,如点击链接、填写表单等。 -
生成报告:可以通过 Puppeteer 生成网页的 PDF 报告或截图,方便分享和存档。 -
支持现代网页特性:Puppeteer 支持最新的 Web API 和特性,如 Service Workers、WebSockets 等。 -
可扩展性:开发者可以根据需要自定义 Puppeteer 的行为,添加中间件、插件等。
PuppeteerSharp 是 Puppeteer 的 .NET 版本,允许开发者在 .NET 应用程序中使用 Puppeteer 提供的浏览器自动化功能。它是一个开源库,可以通过 NuGet 包 PuppeteerSharp 轻松安装和使用。
PuppeteerSharp 的 API 设计与 Puppeteer 很相似,这使得那些熟悉 Puppeteer 的开发者可以很容易上手,同时它也提供了与 .NET 生态系统的集成,便于在 .NET 应用程序中使用。
Sample
markdown-nice 开源版本已经不更新了,所以自己 fork 了一个版本并且打包了一个 docker 镜像来方便部署,并做了一些自定义,因为不好直接通过某个按钮的点击事件或者设置某个值来转换,所以自己写了一个方法暴露了出来,通过这个方法来实现 markdown 到微信公众号 html 的转换

首先添加 PuppeteerSharp NuGet 包的引用
private static readonly AsyncLock BrowserLock = new();
private static IBrowser? _browser;
private static async Task<string> RenderMarkdown(string markdown)
{
if (_browser is null)
{
using (await BrowserLock.LockAsync())
{
if (_browser is null)
{
// 首先通过 BrowserFetcher 下载浏览器
// https://github.com/hardkoded/puppeteer-sharp
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
// 启动浏览器
_browser = await Puppeteer.LaunchAsync();
}
}
}
// 创建一个 page
await using var page = await _browser.NewPageAsync();
// 打开某个网页,并等待网络请求加载结束
await page.GoToAsync("https://mdnice.weihanli.xyz", WaitUntilNavigation.Networkidle0);
// 调用 `parseMdToHtml` 方法并传入 markdown 内容作为参数,并获取返回的 html
var html = await page.EvaluateFunctionAsync<string>("parseMdToHtml", markdown);
// close 当前 page
await page.CloseAsync();
return html;
}
More
大家有需要也可以直接使用,或者也可以自己部署哈
我自己部署的地址就是前面代码里的地址:https://mdnice.weihanli.xyz/
docker image: https://hub.docker.com/r/weihanli/mdnice
自己部署(根据需要自行调整:
docker run --name mdnice -d -p 9000:80 --restart always weihanli/mdnice:latest
References
-
https://github.com/puppeteer/puppeteer -
https://github.com/hardkoded/puppeteer-sharp -
https://mdnice.weihanli.xyz/ -
https://github.com/WeihanLi/markdown-nice

