如何在 F# 中使用 Playwright Sharp 实现浏览器自动化
How to use Playwright Sharp in F# for Browser Automation
我想这是一个经典的 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# 不支持
async
计算表达式 yet 中的 DisposeAsync
,因此浏览器无法正确处理。如果需要,您可以在块的末尾添加 do! browser.DisposeAsync().AsTask() |> Async.AwaitTask
以手动执行此操作。
- F# 要求我们明确忽略不需要的 return 值,我通过
Async.Ignore
. 完成了这一点
从 F# 6 开始,任务现在通过 task computation expression 本机支持。语法几乎与 Brian Berns 的回答中的异步计算表达式相同,只是您不再需要在每个 let!
、use!
或 do!
绑定上调用 Async.AwaitTask
.
let screenshotTask =
task {
use! playwright = Playwright.CreateAsync ()
use! browser = playwright.Chromium.LaunchAsync ()
let! page = browser.NewPageAsync ()
let! _ = page.GotoAsync "https://www.bing.com"
let! _ = page.ScreenshotAsync (PageScreenshotOptions(Path = "screenshot.png"))
return ()
}
screenshotTask.Wait ()
我想这是一个经典的 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# 不支持
async
计算表达式 yet 中的DisposeAsync
,因此浏览器无法正确处理。如果需要,您可以在块的末尾添加do! browser.DisposeAsync().AsTask() |> Async.AwaitTask
以手动执行此操作。 - F# 要求我们明确忽略不需要的 return 值,我通过
Async.Ignore
. 完成了这一点
从 F# 6 开始,任务现在通过 task computation expression 本机支持。语法几乎与 Brian Berns 的回答中的异步计算表达式相同,只是您不再需要在每个 let!
、use!
或 do!
绑定上调用 Async.AwaitTask
.
let screenshotTask =
task {
use! playwright = Playwright.CreateAsync ()
use! browser = playwright.Chromium.LaunchAsync ()
let! page = browser.NewPageAsync ()
let! _ = page.GotoAsync "https://www.bing.com"
let! _ = page.ScreenshotAsync (PageScreenshotOptions(Path = "screenshot.png"))
return ()
}
screenshotTask.Wait ()