diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 90153f4..410c9c3 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/checkout@main
- name: Run
- uses: GabrielBB/xvfb-action@v1
+ uses: coactions/setup-xvfb@main
with:
run: dotnet run
env:
diff --git a/Note163Checkin.csproj b/Note163Checkin.csproj
index d1fca16..622a794 100644
--- a/Note163Checkin.csproj
+++ b/Note163Checkin.csproj
@@ -2,14 +2,14 @@
Exe
- net6.0
+ net7.0
enable
disable
-
-
+
+
diff --git a/Program.cs b/Program.cs
index 2846c71..9e29ca3 100644
--- a/Program.cs
+++ b/Program.cs
@@ -3,12 +3,10 @@
using StackExchange.Redis;
using System.Text.Json;
-HttpClient _scClient = null;
+const int TIMEOUT_MS = 60_000;
+
Conf _conf = Deserialize(GetEnvValue("CONF"));
-if (!string.IsNullOrWhiteSpace(_conf.ScKey))
-{
- _scClient = new HttpClient();
-}
+HttpClient _scClient = new();
#region redis
@@ -45,7 +43,7 @@
if (isInvalid)
{
- cookie = await Login(user.Username, user.Password);
+ cookie = await GetCookie(user);
(isInvalid, result) = await IsInvalid(cookie);
Console.WriteLine("login获取cookie,状态:{0}", isInvalid ? "无效" : "有效");
if (isInvalid)
@@ -105,7 +103,7 @@
return (result.Contains("error", StringComparison.OrdinalIgnoreCase), result);
}
-async Task Login(string username, string password)
+async Task GetCookie(User user)
{
var launchOptions = new LaunchOptions
{
@@ -114,32 +112,76 @@ async Task Login(string username, string password)
ExecutablePath = @"/usr/bin/google-chrome"
};
var browser = await Puppeteer.LaunchAsync(launchOptions);
- Page page = await browser.DefaultContext.NewPageAsync();
-
- await page.GoToAsync("https://note.youdao.com/web", 60_000);
- await page.WaitForSelectorAsync(".login-btn", new WaitForSelectorOptions { Visible = true });
- await page.TypeAsync(".login-username", username);
- await page.TypeAsync(".login-password", password);
- await Task.Delay(5_000);
- await page.ClickAsync(".login-btn");
- await page.WaitForSelectorAsync("ydoc-app", new WaitForSelectorOptions { Visible = true });
-
- var client = await page.Target.CreateCDPSessionAsync();
- var ckObj = await client.SendAsync("Network.getAllCookies");
- var cks = ckObj.Value("cookies")
- .Where(p => p.Value("domain").Contains("note.youdao.com"))
- .Select(p => $"{p.Value("name")}={p.Value("value")}");
-
- await browser.DisposeAsync();
- return string.Join(';', cks);
+ IPage page = await browser.DefaultContext.NewPageAsync();
+
+ await page.GoToAsync("https://note.youdao.com/web", TIMEOUT_MS);
+
+ bool isLogin = false;
+ string cookie = "fail";
+ try
+ {
+ #region 登录
+
+ //登录
+ _ = Login(page, user);
+ int totalDelayMs = 0, delayMs = 100;
+ while (true)
+ {
+ if ((isLogin = IsLogin(page))
+ || totalDelayMs > TIMEOUT_MS)
+ {
+ break;
+ }
+ await Task.Delay(delayMs);
+ totalDelayMs += delayMs;
+ }
+
+ if (isLogin)
+ {
+ var client = await page.Target.CreateCDPSessionAsync();
+ var ckObj = await client.SendAsync("Network.getAllCookies");
+ var cks = ckObj.Value("cookies")
+ .Where(p => p.Value("domain").Contains("note.youdao.com"))
+ .Select(p => $"{p.Value("name")}={p.Value("value")}");
+ cookie = string.Join(';', cks);
+ }
+
+ #endregion
+ }
+ catch (Exception ex)
+ {
+ cookie = "ex";
+ Console.WriteLine($"处理Page时出现异常!{ex.Message};{ex.StackTrace}");
+ }
+ finally
+ {
+ await browser.DisposeAsync();
+ }
+
+ return cookie;
}
+async Task Login(IPage page, User user)
+{
+ try
+ {
+ string js = await _scClient.GetStringAsync(_conf.JsUrl);
+ await page.EvaluateExpressionAsync(js.Replace("@U", user.Username).Replace("@P", user.Password));
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Login时出现异常!{ex.Message}. {ex.StackTrace}");
+ }
+}
+
+bool IsLogin(IPage page) => !page.Url.Contains(_conf.LoginStr, StringComparison.OrdinalIgnoreCase);
+
async Task Notify(string msg, bool isFailed = false)
{
Console.WriteLine(msg);
if (_conf.ScType == "Always" || (isFailed && _conf.ScType == "Failed"))
{
- await _scClient?.GetAsync($"https://sc.ftqq.com/{_conf.ScKey}.send?text={msg}");
+ await _scClient.GetAsync($"https://sc.ftqq.com/{_conf.ScKey}.send?text={msg}");
}
}
@@ -160,6 +202,8 @@ class Conf
public string ScType { get; set; }
public string RdsServer { get; set; }
public string RdsPwd { get; set; }
+ public string JsUrl { get; set; } = "https://github.com/BlueHtml/pub/raw/main/code/js/note163login.js";
+ public string LoginStr { get; set; } = "signIn";
}
class User
diff --git a/README.md b/README.md
index 464a983..1b0ac7e 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,8 @@
"RdsPwd": "ppp" //redis密码,选填
}
```
- `RdsServer`和`RdsPwd`是选填的,用于配置redis,来存储cookie。后续可以重用这个cookie,避免频繁登录账号。建议配置一下,可以使用[redislabs](https://app.redislabs.com/)的免费套餐。
+ - `RdsServer`和`RdsPwd`是选填的,用于配置redis,来存储cookie。后续可以重用这个cookie,避免频繁登录账号。建议配置一下,可以使用[redislabs](https://app.redislabs.com/)的免费套餐。
+ - `JsUrl`和`LoginStr`这2个字段是用来登录账号的,已经设置好了默认值,**不建议**修改,所以上面的配置中没有列出来。详细请查看源码。
**步骤图示如下:**
