目录

Puppeteer

Puppeteer Sharp 原生支持 DevTools 协议,可以驱动应用程序已嵌入的浏览器。 本教程介绍连接代码,以及该连接不涵盖的内容。

Puppeteer Sharp is the .NET port of Puppeteer. It speaks the Chrome DevTools Protocol, or CDP, natively, so it connects to DotNetBrowser with nothing more than the endpoint URL.

Read DevTools Protocol first for the rules that apply to every automation tool.

Prerequisites 

Reference the PuppeteerSharp NuGet package in the project that runs the scenario.

Puppeteer Sharp can download a Chromium build through BrowserFetcher. That step is unnecessary here, because the browser it drives is the one your application already runs.

Enabling the endpoint 

Create the engine with RemoteDebuggingPort set to a free port, as described in DevTools Protocol. The example uses 9223.

Connecting Puppeteer 

Point ConnectOptions.BrowserURL at the endpoint:

C#
VB

ConnectOptions options = new ConnectOptions
{
    BrowserURL = $"http://127.0.0.1:{RemoteDebuggingPort}",
};

Dim options As New ConnectOptions With {
        .BrowserURL = $"http://127.0.0.1:{RemoteDebuggingPort}"
        }

Then pass those options to Puppeteer.ConnectAsync and work with the page that is already open:

C#
VB

PuppeteerSharp.IBrowser browser =
    await PuppeteerSharp.Puppeteer.ConnectAsync(options);

await browser.DefaultContext.OverridePermissionsAsync(LocationUrl, new[]
{
    OverridePermission.Geolocation
});

IPage page = (await browser.PagesAsync()).FirstOrDefault();
await page.GoToAsync(LocationUrl);
await page.WaitForSelectorAsync("title");

await page.SetGeolocationAsync(new GeolocationOption
{
    Latitude = 42.746635M, Longitude = -75.770045M
});
await (await page.QuerySelectorAsync("#map")).ScrollIntoViewAsync();

Dim puppeteerBrowser As IBrowser =
        Await PuppeteerSharp.Puppeteer.ConnectAsync(options)

Await puppeteerBrowser.DefaultContext.OverridePermissionsAsync(
    LocationUrl,
    New OverridePermission() {OverridePermission.Geolocation}
    )

Dim page As IPage = (Await puppeteerBrowser.PagesAsync()).FirstOrDefault()
Await page.GoToAsync(LocationUrl)
Await page.WaitForSelectorAsync("title")

Await page.SetGeolocationAsync(New GeolocationOption With {
                                  .Latitude = 42.746635D,
                                  .Longitude = - 75.770045D
                                  })
Await (Await page.QuerySelectorAsync("#map")).ScrollIntoViewAsync()

ConnectAsync attaches to the running engine and returns a browser object. PagesAsync returns the pages open in the engine; the example takes the first, which is the one shown in the BrowserView control.

What the connection does not cover 

Puppeteer does not own this browser process, so the parts of its API that assume ownership do not apply. NewPageAsync fails: pages come from IEngine.CreateBrowser, not from Puppeteer. The launch options that configure a browser Puppeteer starts itself have nothing to act on either.

Threading and lifetime 

The example starts the connection right after Navigation.LoadUrl, on a background task, so the engine is running by the time Puppeteer attaches. Puppeteer calls are asynchronous and run off the UI thread; marshal results back before touching controls.

The IBrowser name collision 

Both libraries define an IBrowser interface. In C#, the example resolves this with an alias:

using IBrowser = DotNetBrowser.Browser.IBrowser;

PuppeteerSharp.IBrowser is then written out in full where it is needed. The VB.NET example qualifies the DotNetBrowser type instead, as DotNetBrowser.Browser.IBrowser.

The complete example is available in our repository: C#, VB.NET.