{"id":30971603,"url":"https://github.com/dusrdev/puppeteersharptoolkit","last_synced_at":"2025-09-12T02:22:45.881Z","repository":{"id":312343882,"uuid":"1035915016","full_name":"dusrdev/PuppeteerSharpToolkit","owner":"dusrdev","description":"Lightweight Plugin framework for PuppeteerSharp","archived":false,"fork":false,"pushed_at":"2025-08-13T14:21:25.000Z","size":2972,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-06T18:53:04.432Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dusrdev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-11T09:31:46.000Z","updated_at":"2025-08-13T09:23:42.000Z","dependencies_parsed_at":"2025-08-30T00:58:23.956Z","dependency_job_id":"c8104f50-ee21-42f6-ac25-690974a579ef","html_url":"https://github.com/dusrdev/PuppeteerSharpToolkit","commit_stats":null,"previous_names":["dusrdev/puppeteersharptoolkit"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dusrdev/PuppeteerSharpToolkit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dusrdev%2FPuppeteerSharpToolkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dusrdev%2FPuppeteerSharpToolkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dusrdev%2FPuppeteerSharpToolkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dusrdev%2FPuppeteerSharpToolkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dusrdev","download_url":"https://codeload.github.com/dusrdev/PuppeteerSharpToolkit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dusrdev%2FPuppeteerSharpToolkit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274743522,"owners_count":25341135,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-12T02:00:09.324Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-12T02:22:44.852Z","updated_at":"2025-09-12T02:22:45.867Z","avatar_url":"https://github.com/dusrdev.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PuppeteerSharpToolkit\n\nPuppeteerSharpToolkit is a high-performance, AOT-friendly plugin toolkit for PuppeteerSharp. It’s a modern reimagining of the [PuppeteerExtraSharp](https://github.com/Overmiind/Puppeteer-sharp-extra) pattern with a new entry point ([PluginManager](src/PuppeteerSharpToolkit/PluginManager.cs)), focused on trimming- and AOT-safe code, reduced allocations, and startup speed. It is not a drop-in replacement for `PuppeteerExtraSharp`; APIs and behaviors have been redesigned for performance and clarity.\n\n## Why this package exists\n\n- **Updated core**: Bumps PuppeteerSharp dependencies to a more modern stack.\n- **.NET 9 support**: Targets .NET 9, unlocking ahead-of-time (AOT) compilation and aggressive trimming for small, fast binaries.\n- **Performance-first design**: Rewritten internals to avoid reflection and embedded DLL tricks; optimized for minimal allocations and startup cost.\n- **Dropped RestSharp**: No longer depends on RestSharp.\n- **Dropped NewtonSoftJson**: No longer uses NewtonSoft - `System.Text.Json` is the new king.\n\n## Quickstart\n\n```csharp\n// Initialize the plugin manager\nvar manager = new PluginManager();\n\n// Register plugins (dependencies first)\nmanager.Register(new AnonymizeUaPlugin());\n\n// Launch the browser with plugins wired\nawait using var browser = await manager.LaunchAsync(new LaunchOptions { Headless = true });\nawait using var page = await browser.NewPageAsync();\nawait page.GoToAsync(\"https://example.com\");\nawait page.ScreenshotAsync(\"example.png\");\n```\n\n## Plugin list\n\n- **Stealth Plugins** – Various evasion techniques to make headless detection harder.\n- **[Anonymize UA Plugin](src/PuppeteerSharpToolkit/Plugins/AnonymizeUaPlugin.cs)** – Anonymizes the user-agent on all pages.\n- **[ReCAPTCHA Plugin](src/PuppeteerSharpToolkit/Plugins/Recaptcha/RecapchaPlugin.cs)** – Solves reCAPTCHAs automatically.\n- **[Block Resources Plugin](src/PuppeteerSharpToolkit/Plugins/BlockResourcesPlugin.cs)** – Blocks images, documents, and other resource types to speed up navigation.\n\n## API\n\n### Stealth Plugins\n\nStealth related plugins are made for evading detection, usually by injecting scripts at specific times at which websites try to detect bots.\n\nThe available evasion plugins are the following: [ChromeAppPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/ChromeAppPlugin.cs), [ChromeSciPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/ChromeSciPlugin.cs), [CodecPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/CodecPlugin.cs), [ContentWindowPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/ContentWindowPlugin.cs), [EvasionPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/EvasionPlugin.cs), [HardwareConcurrencyPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/HardwareConcurrencyPlugin.cs), [LanguagesPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/LanguagesPlugin.cs), [LoadTimesPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/LoadTimesPlugin.cs), [OutDimensionsPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/OutDimensionsPlugin.cs), [PermissionsPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/PermissionsPlugin.cs), [StackTracePlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/StackTracePlugin.cs), [UserAgentPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/UserAgentPlugin.cs), [VendorPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/VendorPlugin.cs), [WebDriverPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/WebDriverPlugin.cs), [WebGLPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/WebGlPlugin.cs).\n\nIn this example we'll use [ChromeSciPlugin](src/PuppeteerSharpToolkit/Plugins/Stealth/ChromeSciPlugin.cs) which patches \"chrome.app\" and some other chrome APIs that are used by bot detection scripts.\n\n```csharp\nvar manager = new PluginManager();\nmanager.Register(new ChromeSciPlugin());\n\n// Continue with browser and page\n```\n\nTo make life a bit easier, [Stealth](src/PuppeteerSharpToolkit/Plugins/Stealth/Stealth.cs) is a static class that provides some static methods:\n\n```csharp\nPuppeteerPlugin[] GetStandardEvasions(params PuppeteerPlugin[] pluginOverride);\n// Which returns an array of most stealth plugins.\n// The override allows you to initialize any that you with custom arguments\n// Any override that you supply will be used instead of calling the default plugin ctor\n\nTask RegisterUtilsAsync(IPage page);\n// This function register `utils.js` on a page, it is required by some scripts\n// You could also use it if you implement your own plugin, which injects a script\n// ... that can rely on `utils.js`\n```\n\nSo in essence you could register a suite of stealth plugins in one go:\n\n```csharp\nvar manager = new PluginManager();\nmanager.Register(Stealth.GetStandardEvasions());\n```\n\n### [AnonymizeUaPlugin](src/PuppeteerSharpToolkit/Plugins/AnonymizeUaPlugin.cs)\n\nAnonymizeUaPlugin is used to transform the user agent on any page as soon as it launches.\n\n```csharp\n// Initialize the plugin manager\nvar manager = new PluginManager();\n// Initialize the plugin\nvar plugin = new AnonymizeUaPlugin();\n// Register the plugin\nmanager.Register(plugin);\n// by default it will replace headless with regular chrome\n// and set platform to windows\n// you can also add your own custom transformation at any time by changing the function\nplugin.UserAgentTransformer = ua =\u003e \"whatever\";\n// Initialize browser and page + continue with whatever else\n```\n\n### [RecaptchaPlugin](src/PuppeteerSharpToolkit/Plugins/Recaptcha/RecapchaPlugin.cs)\n\n- `Anti-Captcha` provider is disabled pending better solution for their requirement to get recaptcha key.\n- `2Captcha` provider is disabled pending tests using their API to ensure stability.\n\nRecaptchaPlugin is used in conjunction with Recaptcha solving providers, at this state [AntiCaptchaProvider](src/PuppeteerSharpToolkit/Plugins/Recaptcha/AntiCaptcha/AntiCaptchaProvider.cs) and [TwoCaptchaProvider](src/PuppeteerSharpToolkit/Plugins/Recaptcha/Provider/TwoCaptchaProvider.cs) are supported, but this is extensible so you add your own.\n\nThe following is an example with `AntiCaptcha`\n\n```csharp\n// have HttpClient instance ready (it is used to send the requests)\nusing var client = new HttpClient(); // initialization as example\n                                     // best practices will use a factory/singleton\n// Initialize the plugin manager\nvar manager = new PluginManager();\n// Initialize the provider (HttpClient, userKey, ProviderOptions)\nvar provider = new AntiCaptchaProvider(client, \"sampleKey\", ProviderOptions.Default);\n// Default provider options can be used or inferred if omitted.\n// Initialize plugin\nvar plugin = new RecaptchaPlugin(provider);\n// Register the plugin\nmanager.Register(plugin);\n// Initialize browser and page\nawait using var browser = await manager.LaunchAsync();\nawait using var page = await browser.NewPageAsync();\n// go to page with captcha\nawait page.GoToAsync(\"https://patrickhlauke.github.io/recaptcha/\");\n// now solve captcha at page\nawait plugin.SolveCaptchaAsync(page); // Also accepts proxyStr and cancellationToken.\n```\n\nFor [2captcha](https://2captcha.com/ru) simply use the [TwoCaptchaProvider](src/PuppeteerSharpToolkit/Plugins/Recaptcha/TwoCaptcha/TwoCaptchaProvider.cs) instead.\n\n### [BlockResourcesPlugin](src/PuppeteerSharpToolkit/Plugins/BlockResourcesPlugin.cs)\n\nThis plugin is used to blocks page resources in Puppeteer requests (img, documents etc.)\n\n```csharp\n// Initialize the plugin manager\nvar manager = new PluginManager();\n// Initialize the plugin\nvar plugin = new BlockResourcesPlugin();\n// Register the plugin\nmanager.Register(plugin);\n// Initialize browser and page\nawait using var browser = await manager.LaunchAsync();\nawait using var page = await browser.NewPageAsync();\n// Create a rule\nvar blockGoogle = new BlockRule() {\n    SitePattern = new Regex(\"google\"), // SitePattern applies only to specific urls by pattern\n                                       // You can also point it to a GeneratedRegex\n    IPage = page, // it will affect this instance of the page\n    ResourceType = ResourceType.Scripts // Block scripts\n};\n// Add rule\nplugin.AddRule(blockGoogle);\n```\n\nYou can also inspect rules on the plugin, as well as add or remove rules at any point. removing rules uses a `Func\u003cBlockRule, bool\u003e` predicate to select the rules to remove.\n\n## Core API\n\n- Plugin registration: [PluginManager](src/PuppeteerSharpToolkit/PluginManager.cs).Register(params [PuppeteerPlugin](src/PuppeteerSharpToolkit/Plugins/PuppeteerPlugin.cs)[] plugins)\n- Launch: await [PluginManager](src/PuppeteerSharpToolkit/PluginManager.cs).LaunchAsync(LaunchOptions options)\n- Connect: await [PluginManager](src/PuppeteerSharpToolkit/PluginManager.cs).ConnectAsync(ConnectOptions options)\n\n## Caveats / Testing\n\n[RecaptchaPlugin](src/PuppeteerSharpToolkit/Plugins/Recaptcha/RecapchaPlugin.cs) is a clean abstraction, and the tests are mainly testing the specific providers, these tests require having API keys for said providers.\n\nTo set the API keys, `dotnet` user secrets is used, it must be configured when inside the test project directory:\n\n```bash\ndotnet user-secrets set [secretName] [secretValue]\n```\n\n- For [AntiCaptchaProvider](src/PuppeteerSharpToolkit/Plugins/Recaptcha/AntiCaptcha/AntiCaptchaProvider.cs): `secretName = \"AntiCaptchaKey\"`\n- For [TwoCaptchaProvider](src/PuppeteerSharpToolkit/Plugins/Recaptcha/TwoCaptcha/TwoCaptchaProvider.cs): `secretName = \"TwoCaptchaKey\"`\n\nAll Recaptcha tests are marked as `Explicit` and will not execute when running the full test suite (unless specifically asked for), this is to avoid burning API usage.\n\nIf you do want to run them use:\n\n```bash\ndotnet run --explicit on/only\n```\n\nAlso, each provider test will be skipped automatically if the required API key wasn't found in user secrets, so if for example you only have an API key for `AntiCaptcha` - only the tests related to this provider will run.\n\n## Contribution\n\nPatches, performance improvements, and fixes are welcome. Focus is on keeping the core lean and compatible with modern .NET publishing scenarios.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdusrdev%2Fpuppeteersharptoolkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdusrdev%2Fpuppeteersharptoolkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdusrdev%2Fpuppeteersharptoolkit/lists"}