lampac/Shared/PlaywrightCore/PlaywrightBrowser.cs
lampac-talks f843f04fd4 chore: initial commit 154.3
Signed-off-by: lampac-talks <lampac-talks@users.noreply.github.com>
2026-01-30 16:23:09 +03:00

231 lines
6.9 KiB
C#

using Microsoft.Playwright;
using Shared.Models;
using Shared.Models.Base;
namespace Shared.PlaywrightCore
{
public class PlaywrightBrowser : IDisposable
{
public static PlaywrightStatus Status
{
get
{
if (Chromium.Status == PlaywrightStatus.NoHeadless || Firefox.Status != PlaywrightStatus.disabled)
return PlaywrightStatus.NoHeadless;
if (Chromium.Status == PlaywrightStatus.headless)
return PlaywrightStatus.headless;
return PlaywrightStatus.disabled;
}
}
public bool IsCompleted
{
get
{
if (chromium != null)
return chromium.IsCompleted;
return firefox.IsCompleted;
}
}
public TaskCompletionSource<string> completionSource
{
get
{
if (chromium != null)
return chromium.completionSource;
return firefox.completionSource;
}
}
public Chromium chromium = null;
public Firefox firefox = null;
public PlaywrightBrowser(string priorityBrowser = null)
{
if (priorityBrowser == "firefox" && Firefox.Status != PlaywrightStatus.disabled)
{
firefox = new Firefox();
return;
}
chromium = new Chromium();
}
public void SetFailedUrl(string url)
{
if (chromium != null)
{
chromium.failedUrl = url;
}
else
{
firefox.failedUrl = url;
}
}
async public Task<IPage> NewPageAsync(string plugin, Dictionary<string, string> headers = null, (string ip, string username, string password) proxy = default, bool keepopen = true, bool imitationHuman = false, bool deferredDispose = false)
{
try
{
if (chromium == null && firefox == null)
return default;
IPage page = default;
if (chromium != null)
page = await chromium.NewPageAsync(plugin, headers, proxy, keepopen: keepopen, imitationHuman: imitationHuman, deferredDispose: deferredDispose).ConfigureAwait(false);
else
page = await firefox.NewPageAsync(plugin, headers, proxy, keepopen: keepopen).ConfigureAwait(false);
return page;
}
catch { return default; }
}
public void SetPageResult(string val)
{
try
{
if (chromium != null)
{
chromium.IsCompleted = true;
chromium.completionSource.SetResult(val);
}
else
{
firefox.IsCompleted = true;
firefox.completionSource.SetResult(val);
}
}
catch { }
}
public Task<string> WaitPageResult(int seconds = 10)
{
try
{
if (chromium != null)
return chromium.WaitPageResult(seconds);
return firefox.WaitPageResult(seconds);
}
catch { return default; }
}
public Task WaitForAnySelectorAsync(IPage page, params string[] selectors)
{
var tasks = selectors.Select(selector =>
page.WaitForSelectorAsync(selector)
).ToArray();
return Task.WhenAny(tasks);
}
async public Task ClearContinueAsync(IRoute route, IPage page)
{
var cookies = await page.Context.CookiesAsync();
if (cookies == null || cookies.Count == 0)
{
// нету куки, продолжаем
await route.ContinueAsync();
return;
}
var filteredCookies = cookies.Where(c => c.Name != "cf_clearance").Select(c => new Cookie
{
Name = c.Name,
Value = c.Value,
Domain = c.Domain,
Path = c.Path,
Expires = c.Expires,
HttpOnly = c.HttpOnly,
Secure = c.Secure,
SameSite = c.SameSite
}).ToList();
if (filteredCookies.Count == cookies.Count)
{
// Если куки не содержат cf_clearance, продолжаем
await route.ContinueAsync();
return;
}
if (filteredCookies.Count == 0)
{
// после удаления cf_clearance не осталось других куки
await page.Context.ClearCookiesAsync();
await route.ContinueAsync();
return;
}
await page.Context.ClearCookiesAsync();
await page.Context.AddCookiesAsync(filteredCookies);
await route.ContinueAsync();
}
public void Dispose()
{
chromium?.Dispose();
firefox?.Dispose();
}
async public static Task<string> Get(BaseSettings init, string url, List<HeadersModel> headers = null, (string ip, string username, string password) proxy = default, List<Cookie> cookies = null)
{
try
{
using (var browser = new PlaywrightBrowser(init?.priorityBrowser))
{
var page = await browser.NewPageAsync(init?.plugin, headers?.ToDictionary(), proxy).ConfigureAwait(false);
if (page == null)
return null;
if (cookies != null)
await page.Context.AddCookiesAsync(cookies).ConfigureAwait(false);
IResponse response = default;
if (browser.firefox != null)
{
response = await page.GotoAsync(url, new PageGotoOptions() { WaitUntil = WaitUntilState.DOMContentLoaded }).ConfigureAwait(false);
}
else
{
response = await page.GotoAsync($"view-source:{url}", new PageGotoOptions()
{
Timeout = 10_000,
WaitUntil = WaitUntilState.DOMContentLoaded
}).ConfigureAwait(false);
}
if (response != null)
{
string result = await response.TextAsync().ConfigureAwait(false);
PlaywrightBase.WebLog(response.Request, response, result, proxy);
return result;
}
}
}
catch { }
return null;
}
}
}