如何在 F# 中使用 Playwright Sharp 进行浏览器自动化

问题描述

我想这是一个经典的 C# 到 F# 转换,我还没有完全理解。

我正在尝试使用快速入门自动化浏览器

https://playwright.dev/dotnet/docs/intro

C# 代码

using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewPageAsync();
await page.GotoAsync("http://www.bing.com");
await page.ScreenshotAsync(path: outputFile);

我已经开始了,但已经有点迷失了。

let playwright: Playwright = PlaywrightSharp.Playwright.CreateAsync() |> Async.AwaitTask

类型不正确。我在这里做错了什么?

Error   FS0001  This expression was expected to have type
    'Playwright'    
but here has type
    'Async<IPlaywright>'    

解决方法

您可以使用 TaskBuilder 框架 https://github.com/rspeele/TaskBuilder.fs

dotnet 添加包 Taskbuilder.fs

task {    
    use! playwright =  Playwright.CreateAsync() 
    let! browser =  playwright.Chromium.LaunchAsync()
    let! page = browser.NewPageAsync()
    
    let! response = page.GoToAsync("http://www.bing.com")
    let! title =  page.GetTitleAsync()

    printfn "%s" title

}
|> Task.WaitAll
,

一种方法是使用 F# 对 async computation expressions 的内置支持。翻译看起来像这样:

let (~~) = Async.AwaitTask

async {
    use! playwright = ~~Playwright.CreateAsync()
    let! browser = ~~playwright.Chromium.LaunchAsync()
    let! page = ~~browser.NewPageAsync()
    do! ~~page.GoToAsync("http://www.slashdot.com") |> Async.Ignore
    do! ~~page.ScreenshotAsync(outputFile) |> Async.Ignore
} |> Async.RunSynchronously

这里有一些你需要知道的微妙之处:

  • F# 有自己的异步类型,称为 Async<'T>。我已经使用 Async.AwaitTask 从 C# 样式的任务转换而来,并定义了一个前缀运算符 ~~,使其看起来更简洁。
  • F# 不支持 DisposeAsync 计算表达式 yet 中的 async,因此浏览器无法正确处理。如果需要,您可以在块的末尾添加 do! browser.DisposeAsync().AsTask() |> Async.AwaitTask 以手动执行此操作。
  • F# 要求我们明确忽略不需要的返回值,我已经通过 Async.Ignore 做到了这一点。