Ang*_*ker 4 .net c# webautomation chromium puppeteer-sharp
我正在尝试在服务器端环境中在一秒钟内生成网页图像。这些请求可以同时来自网络。为此,我使用了运行良好的Puppeteer-Sharp库。在后端,它使用 Chromium 加载页面,然后对其进行截图。
问题是需要一段时间才能开始。例如,请注意 readme.md 示例代码中的时间(来自我的电脑):
var options = new new LaunchOptions {Headless = true, ExecutablePath = @"c:\foo\chrome.exe"};
var browser = await Puppeteer.LaunchAsync(options).Result; // ~500ms
var page = browser.NewPageAsync().Result; // ~215ms
var webPage = page.GoToAsync("http://www.google.com").Result; // ~500ms
var screenshot = page.ScreenshotAsync(outputFile);
screenshot.wait(); // ~300ms
Run Code Online (Sandbox Code Playgroud)
如您所见,它很容易超过一秒钟。我不知道 Chromium 内部是如何工作的,所以我有几个关于我正在考虑的解决方案的问题。
PuppeteerSharp.Browser对象的线程安全和/或重入?我可以使用来自不同线程的相同浏览器对象吗?我不这么认为,因为它与内存中的特定 Chromium 实例相关联。 .LaunchAsync和删除.NetPageAsync将显着加快操作速度。PuppeteerSharp.Browser对象池会起作用吗?例如,我可以预先分配其中的 5 个并对其执行.NetPageAsync。然后传入的请求将使用池中的对象。这是一种可行的方法吗?尽管仍有许多改进正在进行,但 Puppeteer-Sharp 是线程安全的。为了提高加载性能,您可以采取一些方法。
启动一个浏览器,然后连接到它
您可以启动一个(真实的)浏览器,然后使用该ConnectAsync方法连接到它。
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = false,
});
var theBrowser1 = await Puppeteer.ConnectAsync(new ConnectOptions { BrowserWSEndpoint = browser.WebSocketEndpoint });
var theBrowser2 = await Puppeteer.ConnectAsync(new ConnectOptions { BrowserWSEndpoint = browser.WebSocketEndpoint });
var page1 = await theBrowser1.NewPageAsync();
var page2 = await theBrowser2.NewPageAsync();
await Task.WhenAll(
page1.GoToAsync("https://www.stackoverflow.com"),
page2.GoToAsync("https://serverfault.com/")
);
Run Code Online (Sandbox Code Playgroud)
我知道代码不是并行运行的,但是您会了解重用相同的浏览器。
在同一浏览器上创建新页面
如果您使用的是TPL,则使用相同浏览器从不同线程创建新页面应该不会有任何问题。
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = false,
});
var urls = new string[]
{
"https://www.stackoverflow.com",
"https://www.stackoverflow.com",
"https://www.stackoverflow.com",
"https://www.stackoverflow.com",
"https://www.stackoverflow.com",
"https://www.stackoverflow.com",
"https://www.stackoverflow.com",
"https://www.stackoverflow.com",
"https://www.stackoverflow.com",
"https://www.stackoverflow.com",
"https://www.stackoverflow.com"
};
await Task.WhenAll(
urls.Select(url => Task.Factory.StartNew(async () =>
{
var page = await browser.NewPageAsync();
return page.GoToAsync(url);
})));
Run Code Online (Sandbox Code Playgroud)
同样,这个示例只是让您了解如何实现这一点。
页面队列
有一个用户创建了一个 X 页的队列(x 从 0 到 X => NewPage),然后他将从该队列中抓取页面。您可以在此处查看示例。
| 归档时间: |
|
| 查看次数: |
1055 次 |
| 最近记录: |