Playwright使用记录

玖亖伍
2021-08-02 / 0 评论 / 3,303 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年02月25日,已超过753天没有更新,若内容或图片失效,请留言反馈。
Playwright for .NET is the official language port of Playwright, the library to automate Chromium, Firefox and WebKit with a single API.

操作记录

# 安装 Playwright 工具
dotnet tool install --global Microsoft.Playwright.CLI

# 创建项目
dotnet new console -n PlaywrightDemo
cd PlaywrightDemo

# 安装依赖
dotnet add package Microsoft.Playwright --prerelease

# 用Playwright 工具安装浏览器
playwright install
# chromium v888113 downloaded to C:\Users\gsw\AppData\Local\ms-playwright\chromium-888113
# firefox v1268 downloaded to C:\Users\gsw\AppData\Local\ms-playwright\firefox-1268
# webkit v1490 downloaded to C:\Users\gsw\AppData\Local\ms-playwright\webkit-1490
# ffmpeg v1005 downloaded to C:\Users\gsw\AppData\Local\ms-playwright\ffmpeg-1005

# 运行项目(PlaywrightDemo)
dotnet run

# 自动生成代码
playwright codegen

# 打开指定页面(可调试或生成代码)
playwright open https://gsw945.com/

# 以指定的语言、时区、和窗口大小,使用chromium浏览器打开指定页面,生成C#代码
playwright codegen --target csharp --browser chromium --channel chrome --lang "zh-CN" --timezone "Asia/Shanghai" --viewport-size "1920,1080" "https://gsw945.com/"

代码示例

using Microsoft.Playwright;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    /// <summary>
    /// 等待退出
    /// </summary>
    private static ManualResetEvent waitQuitEvent = new ManualResetEvent(initialState: false);

    public static async Task Main()
    {
        // 设置调试相关环境变量
        Environment.SetEnvironmentVariable("PWDEBUG", "console");
        Environment.SetEnvironmentVariable("DEBUG", "pw:api");

        var appDataLocal = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
        Console.WriteLine($"playwright下载浏览器目录: {Path.Combine(appDataLocal, "ms-playwright")}");
        
        List<KeyValuePair<string, string>> envs = new List<KeyValuePair<string, string>>();
        foreach (DictionaryEntry envItem in Environment.GetEnvironmentVariables())
        {
            envs.Add(new KeyValuePair<string, string>((string)envItem.Key, (string)envItem.Value));
        }

        // 创建playwright实例
        using var playwright = await Playwright.CreateAsync();
        // 创建Chromium浏览器实例
        await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions() {
            Headless = false, // 关闭无头模式(有界面)
            Channel = "chrome", // 指定采用chrome浏览器类型
            Devtools = true, // 启用开发者工具
            ChromiumSandbox = false, // 关闭浏览器沙盒
            Env = envs, // 环境变量
            ExecutablePath = string.Empty, // 不指定浏览器可执行文件位置,会自动寻找 ms-playwright 下载的浏览器
        });

        browser.Disconnected += (object sender, IBrowser e) =>
        {
            Console.WriteLine($"On Browser Close");
        };
        // 浏览器上下文
        await using var context = await browser.NewContextAsync(new BrowserNewContextOptions
        {
            ViewportSize = new ViewportSize
            {
                Width = 1536, // 1920 * 0.8
                Height = 864, // 1080 * 0.8
            }, // 视口大小
            Locale = "zh-CN", // 语言(区域)
            TimezoneId = "Asia/Shanghai", // 时区
        });
        context.Close += (object sender, IBrowserContext e) =>
        {
            Console.WriteLine($"On Context Close");
        };

        // 新开页面(空白页)
        var page = await context.NewPageAsync();
        // var page = await browser.NewPageAsync();
        page.Close += (object sender, IPage e) =>
        {
            Console.WriteLine($"On Page Close");
        };
        page.Dialog += async (_, dialog) =>
        {
            Console.WriteLine(dialog.Message);
            await dialog.DismissAsync();
        };
        // 新开的页面跳转(打开)到指定URL
        await page.GotoAsync("https://gsw945.com/");
        // await page.GotoAsync("https://playwright.dev/dotnet");
        // 当前页面截图并保存到指定位置
        var screenshotPath = Path.GetFullPath("screenshot.png");
        await page.ScreenshotAsync(new PageScreenshotOptions
        {
            Path = screenshotPath,
            FullPage = true,
            Type = ScreenshotType.Png,
            OmitBackground = true
        });
        if (File.Exists(screenshotPath))
        {
            Console.WriteLine($"页面截图: {screenshotPath}");
            // File.Delete(screenshotPath);
        }
        // (通过css选择器选择)点击指定的元素(如果元素还未出现在DOM中则等待)
        // refer: https://playwright.dev/dotnet/docs/core-concepts#auto-waiting
        await page.ClickAsync("a[title=\"友情链接\"]");
        // (通过css选择器选择)等待元素出现在DOM中
        await page.WaitForSelectorAsync("#Joe_Baidu_Record");
        // 执行javascript表达式并取得结果
        // refer: https://playwright.dev/dotnet/docs/core-concepts#execution-contexts-playwright-and-browser
        var href = await page.EvaluateAsync<string>("document.location.href");
        Console.WriteLine($"href: {href}");

        // 普通逻辑, 等待console退出
        await StartWait2Exit(context);
    }

    public static async Task StartWait2Exit(IBrowserContext context)
    {
        Console.WriteLine("-".PadLeft(60, '-'));
        Console.WriteLine("Press [Ctrl + C] or [Q] or [Esc] to quit...");
        Console.WriteLine("-".PadLeft(60, '-'));

        // Ctrl + C 捕获
        Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs eventArgs) =>
        {
            eventArgs.Cancel = true;
            Console.WriteLine("[Ctrl + C] pressed, to quit.");
            waitQuitEvent.Set();
        };
        
        Thread t = new Thread(() =>
        {
            while(true)
            {
                // 监听是否关闭了浏览器(playwright 断开连接 或 所有打开的页面全部都关闭了)
                if (!context.Browser.IsConnected || context.Pages.Count < 1)
                {
                    Console.WriteLine("Detect Browser Context Is Not Connected or No Page is Open");
                }
                // 如果输入输出未重定向
                if (!Console.IsInputRedirected && Console.KeyAvailable)
                {
                    // 读取键盘输入
                    ConsoleKeyInfo keyInfo = Console.ReadKey(intercept: true);
                    Console.WriteLine($"Key: {keyInfo.Key}");
                    // Q或ESC键,退出
                    if (keyInfo.Key == ConsoleKey.Q || keyInfo.Key == ConsoleKey.Escape)
                    {
                        break;
                    }
                }
                Thread.Sleep(millisecondsTimeout: 50);
            }
            waitQuitEvent.Set();
        });
        t.IsBackground = true;
        t.Start();

        waitQuitEvent.WaitOne();
        await Task.Yield();
    }
}

参考

1

评论 (0)

取消