首页
友情链接
关于
Search
1
欢迎使用 Typecho
13,185 阅读
2
Playwright使用记录
3,234 阅读
3
Windows上GCC安装
2,094 阅读
4
Unity独立安装后添加IL2CPP等编译组件
2,048 阅读
5
(Windows)以一种访问权限不允许的方式做了一个访问套接字的尝试处理
1,741 阅读
全部博文
游戏开发
Unity
Godot Engine
GDScript
编程代码
C#编程
GoLang编程
PowerShell
开发工具
Git
笔记备忘
登录
Search
标签搜索
docker
Godot
GCC
CMS
Proto.Actor
Actor模型
winpty
msys2
Unity
IL2CPP
package
golang
ssh
proxy
proxychains
minikube
k8s
n2n
PowerShell
ChatGPT
玖亖伍
累计撰写
29
篇文章
累计收到
216
条评论
首页
栏目
全部博文
游戏开发
Unity
Godot Engine
GDScript
编程代码
C#编程
GoLang编程
PowerShell
开发工具
Git
笔记备忘
页面
友情链接
关于
搜索到
13
篇与
的结果
2023-10-26
自定义 node.js Docker 镜像
Dockerfile:FROM ghcr.io/linuxserver/baseimage-alpine:3.18 SHELL ["/bin/bash", "-c"] RUN echo $'#!/bin/bash \n\ set -e \n\ \n\ # Run command with node if the first argument contains a "-" or is not a system command. The last \n\ # part inside the "{}" is a workaround for the following bug in ash/dash: \n\ # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264 \n\ if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ] || { [ -f "${1}" ] && ! [ -x "${1}" ]; }; then \n\ set -- node "$@" \n\ fi \n\ \n\ exec "$@"' > /usr/local/bin/docker-entrypoint.sh RUN chmod a+x /usr/local/bin/docker-entrypoint.sh RUN groups RUN users RUN whoami RUN groupadd --non-unique --gid 1000 node RUN useradd --non-unique --uid 1000 --gid node --shell /bin/bash --create-home node ENV NODE_VERSION 21.1.0 ENV ARCH x64 RUN curl -fsSLO --compressed "https://unofficial-builds.nodejs.org/download/release/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" RUN ls -lha RUN tar -xJf "node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" -C /usr/local --strip-components=1 --no-same-owner RUN rm -f "node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" RUN ln -s /usr/local/bin/node /usr/local/bin/nodejs RUN apk add --no-cache libstdc++ RUN node --version RUN npm --version # RUN wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.bashrc" SHELL="$(which bash)" bash - RUN npm config set registry https://registry.npmmirror.com RUN npm install -g pm2 RUN npm install -g pnpm RUN pnpm --version RUN rm -rf /tmp/* $HOME/.cache ENTRYPOINT ["docker-entrypoint.sh"] CMD [ "node" ]build:docker build --progress plain --rm --tag gsw945/node:v0.0.1 .参考安装 | pnpm - 使用 npm 安装https://github.com/nodejs/docker-node/blob/main/21/alpine3.18/Dockerfilehttps://github.com/linuxserver/docker-baseimage-alpine/pkgs/container/baseimage-alpine/137430303?tag=3.18How to write commands with multiple lines in Dockerfile while preserving the new lines?Dockerfile replicate the host user UID and GID to the image
2023年10月26日
26 阅读
0 评论
0 点赞
2023-10-09
有用的几条Git命令
git fsckgit fsck 命令用于检查 Git 数据库内部的完整性,找出问题对象。这3个选项具体用法如下:git fsck --dangling:显示悬空对象(dangling object),即孤立的提交/树/blobs,不被任何其他对象引用。git fsck --unreachable:显示不可达对象(unreachable object),即不可到达的对象,不被任何一个分支或标签引用。git fsck --lost-found:显示遗失的对象(lost found), 位于 .git/lost-found/ 其他 commit 引用了的对象。总结:dangling 对象不被任何对象引用,但仍在数据库中。unreachable 对象不被任何分支或标签引用,可能在重写历史后出现。lost-found 对象被其他 commit 引用,但不在当前分支或标签中。这3个选项可以帮助我们发现和恢复在重写历史时“丢失”的对象,修复问题。git log示例命令: git log --format="hash: %H%nauthor: %an%ndate: %aI%n%n%B"--fromat参数解释:%H - commit hash (hash 值)%an - author name (作者用户名)%aI - author date, ISO 8601 格式 (提交时间)%B - commit message body (提交信息)%n - 换行符实际应用显示不可达的Commit信息git fsck --unreachable | grep commit | cut -d' ' -f3 | xargs -I {} git log --format="hash: %H%nauthor: %an%ndate: %aI%n%n%B" -n 1 {}参考Look up commit log for commit ID in GitHow can I view a git log of just one user's commits?git fsck: how --dangling vs. --unreachable vs. --lost-found differ?How can I find an unreachable commit hash in a GIT repository by keywords?
2023年10月09日
21 阅读
0 评论
0 点赞
2023-03-27
Ubuntu配置clang环境并编译示例程序
操作步骤添加 gpg 秘钥:wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -添加源 vim /etc/apt/sources.list.d/llvm.list# Focal (20.04) LTS deb http://apt.llvm.org/focal/ llvm-toolchain-focal main deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal main更新 apt 包信息: sudo apt update安装 clang、lld 和 libc++:sudo apt install install clang-17 clang-tools-17 clang-17-doc libclang-common-17-dev libclang-17-dev libclang1-17 clang-format-17 python3-clang-17 clangd-17 clang-tidy-17 sudo apt install lld-17 sudo apt install libc++-17-dev libc++abi-17-devLinux 程序编译:clang++ --std=c++17 -o main main.cppWindows 程序(交叉)编译:clang++ --std=c++17 -target x86_64-pc-windows-gnu -mconsole -o main.exe main.cpp示例程序目录结构:. ├── main.cpp └── pocketpy.hmain.cpp内容:#include <iostream> #include "pocketpy.h" using namespace pkpy; using namespace std; int main(int argc, char** argv) { cout << "C++: hello world!" << endl; VM* vm = new VM(true); // Hello world! vm->exec("print('Python: Hello world!')", "main.py", EXEC_MODE); // Create a list vm->exec("a = [1, 2, 3]", "main.py", EXEC_MODE); // Eval the sum of the list PyVar result = vm->exec("sum(a)", "<eval>", EVAL_MODE); std::cout << py_cast<i64>(vm, result) << endl; // 6 pkpy_delete(vm); return 0; }pocketpy.h 来自项目 blueloveTH/pocketpy:PocketPy is a lightweight(~6000 LOC) Python interpreter for game engines.PocketPy是一个轻量级的Python解释器,为嵌入至游戏引擎而设计。参考LLVM Debian/Ubuntu nightly packagesWelcome to PocketPyPocketPy issues | c example #41
2023年03月27日
236 阅读
1 评论
1 点赞
2023-03-14
windows上docker运行nextcloud
端口映射: 58080 --> 80挂载路径: D:\nextcloud-data --> :/var/www/html环境变量:使用的数据库: SQLITE_DATABASE: nextcloud默认管理员账户: NEXTCLOUD_ADMIN_USER: admin默认管理员密码: NEXTCLOUD_ADMIN_PASSWORD: admin完整命令docker run -d -p 58080:80 -v //d/nextcloud-data:/var/www/html -e SQLITE_DATABASE=nextcloud -e NEXTCLOUD_ADMIN_USER=admin -e NEXTCLOUD_ADMIN_PASSWORD=admin nextcloud:production运行成功后,浏览器打开 http://localhost:58080/ 等待一会儿就会看到如下的页面:<!--参考:https://app.pluralsight.com/library/courses/docker-web-development/table-of-contentshttps://hub.docker.com/_/nextcloud-->
2023年03月14日
109 阅读
0 评论
0 点赞
2023-03-06
文件检索相关命令行工具
BATA cat(1) clone with wings.特性:语法高亮Git 集成不可打印(non-printable)字符可视化自动分页fzfA command-line fuzzy finderfdA simple, fast and user-friendly alternative to 'find'ripgrep((rg))ripgrep recursively searches directories for a regex pattern while respecting your gitignoreripgrep 常用命令示例:# 查看支持的类型(type)列表 rg --type-list # 添加一个自定义的类型 mmkkdd, 后缀名为 *.md, 排除.git、bin、obj、node_modules文件夹,搜索 babel rg --type-add "mmkkdd:*.md" -g "!**/.git" -g "!**/bin" -g "!**/obj" -g "!**/node_modules" --type mmkkdd -- babel # 添加一个自定义的类型 myscript, 后缀名包含 *.ps1,*.cmd,*.bat, 排除.git、bin、obj、node_modules文件夹,搜索 dotnet rg --type-add "myscript:*.{ps1,cmd,bat}" -g "!**/.git" -g "!**/bin" -g "!**/obj" -g "!**/node_modules" --type myscript -- dotnet注意: 参数用引号包裹时,windows上用双引号 ", 类Unix 上用单引号 '。
2023年03月06日
98 阅读
0 评论
0 点赞
2023-01-18
PowerShell片段
简单片段查找命令(示例: 包含Module的命令)Get-Command | Out-String -Stream | Select-String -Pattern "Module" -SimpleMatch -CaseSensitive查看帮助(示例: 查看命令Get-InstalledModule的帮助)Get-Help -Name Get-InstalledModule在线查找模块(示例: 搜索模块Pode)Find-Module -Filter Pode信任仓库PSGallery# 查看仓库 Get-PSRepository # 信任仓库 Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted安装包(示例: 安装模块Pode)Install-Module -Name Pode -AllowClobber -Force自定义对象(类似于 C# 的 匿名类型)[PSCustomObject]@{ 'Command' = [string]'git' }查看对象成员# 实例化对象 $obj = [PSCustomObject]@{ 'Command' = [string]'git' } # 查看全部对象 $obj | Get-Member # 仅查看属性 $obj | Get-Member -MemberType NoteProperty定义类并使用# 定义类 ClassDemo class ClassDemo { [int]$One [string]$Two ClassDemo() {} ClassDemo([int]$one, [string]$two) { $this.One = $one $this.Two = $two } [string]ToString(){ return ("ClassDemo(One={0},Two={1})" -f $this.One, $this.Two) } } # 3种方式实例化 ClassDemo # 1. 使用 ::new() $object1 = [ClassDemo]::new(1,"2") # 2. 使用 New-Object $object2 = New-Object ClassDemo -Property @{ One = 1; Two = "2" } # 3. 使用类型转换 $object3 = [ClassDemo]@{ One = 1; Two = "2" }功能封装判断命令行命令是否存在function IsCommandExists { <# .SYNOPSIS 判断命令行命令是否存在 .DESCRIPTION 判断命令行命令是否存在 .PARAMETER Command 命令 .EXAMPLE PS> IsCommandExists -Command git .EXAMPLE PS> 'git' | IsCommandExists .EXAMPLE PS> [PSCustomObject]@{ 'Command' = [string]'git' } | IsCommandExists .LINK https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_automatic_variables #> [OutputType([bool])] param( [Parameter(Mandatory=$true, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)] [string] $Command ) Get-Command -ErrorAction SilentlyContinue "$Command" | Out-Null if ($?) { return $True } return $False }外部命令行调用# 命令行调用 pwsh 执行 PowerShell 命令 Get-InstalledModule pwsh -NoLogo -Command "& {Get-InstalledModule}"参考PowerShell 文档The PowerShell Best Practices and Style Guide关于基于注释的帮助Strongly type PS custom object propertiesIncorporating Pipelined Input into PowerShell Functions关于类
2023年01月18日
113 阅读
0 评论
0 点赞
2022-06-29
虚拟组网工具n2n源码编译记录
操作环境: Ubuntu 20.4 LTS系统需要安装的编译相关的工具sudo apt install gcc g++ make git vim autoconf -y# clone源码(使用 https://ghproxy.com/ 加速) git clone https://ghproxy.com/https://github.com/ntop/n2n.git n2n-src # 编译配置 cd n2n-src/ ./autogen.sh ./configure # 编译 make # 安装 sudo make install
2022年06月29日
201 阅读
0 评论
0 点赞
2022-05-24
SSH反向代理的使用
准备工作说明:12.34.56.78 为公网服务器, ssh端口为22192.168.1.2 为内网服务器(未开放访问公网), ssh端口为10022192.168.1.5 为本机, 可访问192.168.1.2和12.34.56.78涉及到的命令# 设置SOCKS5代理 ssh -o StrictHostKeyChecking=no 12.34.56.78 -l user0 -p 22 -D 0.0.0.0:12080 -N -v # 设置反向隧道到代理 ssh -o StrictHostKeyChecking=no 192.168.1.2 -l devops -p 10022 -R 8051:127.0.0.1:12080 -N -v # 本机连接到私域服务器,下面的命令在其上执行 ssh 192.168.1.2 -l devops -p 100221. 修改hosts,绕过DNS解析编辑hosts文件,按需设置: sudo vim /etc/hosts119.84.77.214 mirrors.aliyun.com 140.83.35.89 ghproxy.com 65.52.183.205 packages.microsoft.com2. 安装proxychains获取proxychains源码# 临时设置代理 export ALL_PROXY=socks5://127.0.0.1:8051 # 获取proxychains源码 git clone https://ghproxy.com/https://github.com/rofl0r/proxychains-ng.git proxychains-ng-src # 取消临时代理 unset ALL_PROXYproxychains编译和安装cd proxychains-ng-src/ ./configure make sudo make install sudo make install-config修改proxychains配置添加代理: sudo vim /usr/local/etc/proxychains.conf[ProxyList] socks5 127.0.0.1 80513. 使用示例通过proxychains安装.NET6和Powershellproxychains4 wget -c https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo proxychains4 apt update # 安装常用和必要软件 sudo proxychains4 apt install -y apt-transport-https software-properties-common w3m tree # 安装 .NET6和pwsh sudo proxychains4 apt install -y dotnet-sdk-6.0 powershell # 验证 dotnet --info pwsh --version运行filebrowserproxychains4 wget -c https://ghproxy.com/https://github.com/filebrowser/filebrowser/releases/download/v2.21.1/linux-amd64-filebrowser.tar.gz tar -zxvf linux-amd64-filebrowser.tar.gz mkdir data-store /home/devops/filebrowser/filebrowser --address "0.0.0.0" --port "2554" --root /home/devops/filebrowser/data-store # 本地代理(本地访问: http://127.0.0.1:2554/) ssh -o StrictHostKeyChecking=no 192.168.1.2 -l devops -p 10022 -L 2554:127.0.0.1:2554 -N -v
2022年05月24日
189 阅读
0 评论
0 点赞
2022-05-20
Ubuntu上MySQL8备忘
安装mysql# 服务器 sudo apt install mysql-server -y # 客户端 sudo apt install mysql-client -y设置密码并开启远程连接修改mysql配置vim /etc/mysql/mysql.conf.d/mysqld.cnf主要配置内容[mysqld] # mysql 监听主机 bind-address = 0.0.0.0 # mysql X插件 监听主机(如果启用了的话) mysqlx-bind-address = 0.0.0.0修改mysql内部设置超管方式运行mysql# Ubuntu上全新安装的mysql8没有默认启用密码插件 sudo mysql执行如下sql操作-- 修改默认root@localhost使用密码插件并设置密码 ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your password'; -- 添加root允许远程主机访问(如果有必要,务必确保安全) CREATE USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your password'; -- 授予远程访问全部权限 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'; -- 刷新权限 FLUSH PRIVILEGES; exit安装mysql后需要修改忽略表名大小写Windows上,MySQL默认是忽略表名大小写的;Linux上,MySQL默认是区分表名大小写的,且MySQL初始化之后是不允许修改忽略表名大小写配置的,而MySQL安装过程会自动初始化。如下操作参考: How to install MySQL 8.0 with lower_case_table_names=1 on Ubuntu Server 20.04 LTS successfully?如果需要在MySQL安装后修改为忽略表名大小写,则需要删除MySQL数据,重新初始化,所以,如下操作前请备份数据;修改mysql配置vim /etc/mysql/mysql.conf.d/mysqld.cnf主要配置内容[mysqld] lower_case_table_names = 1清理数据(操作前务必备份数据)# 停止服务 sudo service mysql stop # 删除mysql数据文件夹及内部数据 sudo rm -rf /var/lib/mysql # 重新创建mysql数据文件夹并赋予合适的权限 sudo mkdir /var/lib/mysql sudo chown mysql:mysql /var/lib/mysql sudo chmod 700 /var/lib/mysql # 重新初始化mysql sudo mysqld --defaults-file=/etc/mysql/my.cnf --initialize --lower_case_table_names=1 --user=mysql --console # 启动服务 sudo service mysql start # 查看mysql临时密码 sudo grep 'temporary password' /var/log/mysql/error.log # 使用(临时密码)登录mysql sudo mysql -u root -p # 参考前面允许远程配置部分,修改密码可参考的mysql语句-- 查看用户、认证方式、主机等信息 SELECT user,authentication_string,plugin,host FROM mysql.user; -- 是否启用了ssl SHOW VARIABLES LIKE 'have_ssl'; -- 是否忽略大小写 SHOW VARIABLES LIKE 'lower_case_%';
2022年05月20日
292 阅读
0 评论
0 点赞
2021-08-02
Playwright使用记录
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(); } }参考Getting Started | PlaywrightDebugging toolsPlaywright for .NETPlaywrightBrowserBrowserContextPagePage.ScreenshotAsync(options)Page.WaitForSelectorAsync(selector, options)https://github.com/microsoft/playwrighthttps://github.com/microsoft/playwright-dotnet
2021年08月02日
3,234 阅读
0 评论
1 点赞
1
2