├── .gitignore ├── README.md ├── dotnet-csharp ├── .gitignore ├── Kameleo.LocalApi.Examples.sln ├── automate_mobile_profiles_on_desktop │ ├── AutomateMobileProfilesOnDesktop.csproj │ └── Program.cs ├── basic_profile_operations │ ├── BasicProfileOperations.csproj │ └── Program.cs ├── clean_workspace │ ├── CleanWorkspace.csproj │ └── Program.cs ├── connect_with_playwright_to_chrome │ ├── ConnectWithPlaywrightToChrome.csproj │ └── Program.cs ├── connect_with_playwright_to_firefox │ ├── ConnectWithPlaywrightToFirefox.csproj │ └── Program.cs ├── connect_with_puppeteer │ ├── ConnectWithPuppeteer.csproj │ └── Program.cs ├── connect_with_selenium │ ├── ConnectWithSelenium.csproj │ └── Program.cs ├── cookie_robot │ ├── CookieRobot.csproj │ └── Program.cs ├── file_upload_with_selenium │ ├── FileUploadWithSelenium.csproj │ ├── Program.cs │ └── kameleo.png ├── manage_cookies │ ├── ManageCookies.csproj │ └── Program.cs ├── modify_request_response_with_selenium │ ├── ModifyRequestResponseWithSelenium.csproj │ ├── Program.cs │ └── kameleo.svg ├── profile_export_import │ ├── ProfileExportImport.csproj │ └── Program.cs ├── start_browser_with_additional_options │ ├── Program.cs │ └── StartBrowserWithAdditionalOptions.csproj ├── start_with_proxy │ ├── Program.cs │ └── StartWithProxy.csproj ├── take_screenshot_with_puppeteer │ ├── Program.cs │ └── TakeScreenshotWithPuppeteer.csproj └── upgrade_profile │ ├── Program.cs │ └── UpgradeProfile.csproj ├── nodejs ├── .gitignore ├── .prettierrc.json ├── automate_mobile_profiles_on_desktop │ ├── index.js │ └── package.json ├── basic_profile_operations │ ├── index.js │ └── package.json ├── clean_workspace │ ├── index.js │ └── package.json ├── commonjs │ ├── index.js │ └── package.json ├── connect_with_playwright_to_chrome │ ├── index.js │ └── package.json ├── connect_with_playwright_to_firefox │ ├── index.js │ └── package.json ├── connect_with_puppeteer │ ├── index.js │ └── package.json ├── connect_with_selenium │ ├── index.js │ └── package.json ├── cookie_robot │ ├── index.js │ └── package.json ├── eslint.config.mjs ├── manage_cookies │ ├── index.js │ └── package.json ├── package-lock.json ├── package.json ├── profile_export_import │ ├── index.js │ └── package.json ├── start_browser_with_additional_options │ ├── index.js │ └── package.json ├── start_with_proxy │ ├── index.js │ └── package.json ├── take_screenshot_with_puppeteer │ ├── index.js │ └── package.json ├── tsconfig.json └── upgrade_profile │ ├── index.js │ └── package.json └── python ├── .gitignore ├── automate_mobile_profiles_on_desktop └── app.py ├── basic_profile_operations └── app.py ├── clean_workspace └── app.py ├── connect_with_playwright_to_chrome └── app.py ├── connect_with_playwright_to_firefox └── app.py ├── connect_with_puppeteer └── app.py ├── connect_with_selenium └── app.py ├── cookie_robot └── app.py ├── manage_cookies └── app.py ├── profile_export_import └── app.py ├── requirements.txt ├── start_browser_with_additional_options └── app.py ├── start_with_proxy └── app.py ├── take_screenshot_with_puppeteer └── app.py └── upgrade_profile └── app.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 2 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 3 | 4 | # User-specific stuff 5 | .idea/ 6 | 7 | # Gradle and Maven with auto-import 8 | # When using Gradle or Maven with auto-import, you should exclude module files, 9 | # since they will be recreated, and may cause churn. Uncomment if using 10 | # auto-import. 11 | # .idea/artifacts 12 | # .idea/compiler.xml 13 | # .idea/jarRepositories.xml 14 | # .idea/modules.xml 15 | # .idea/*.iml 16 | # .idea/modules 17 | # *.iml 18 | # *.ipr 19 | 20 | # CMake 21 | cmake-build-*/ 22 | 23 | # Mongo Explorer plugin 24 | .idea/**/mongoSettings.xml 25 | 26 | # File-based project format 27 | *.iws 28 | 29 | # IntelliJ 30 | out/ 31 | 32 | # mpeltonen/sbt-idea plugin 33 | .idea_modules/ 34 | 35 | # JIRA plugin 36 | atlassian-ide-plugin.xml 37 | 38 | # Cursive Clojure plugin 39 | .idea/replstate.xml 40 | 41 | # SonarLint plugin 42 | .idea/sonarlint/ 43 | 44 | # Crashlytics plugin (for Android Studio and IntelliJ) 45 | com_crashlytics_export_strings.xml 46 | crashlytics.properties 47 | crashlytics-build.properties 48 | fabric.properties 49 | 50 | # Editor-based Rest Client 51 | .idea/httpRequests 52 | 53 | # Android studio 3.1+ serialized cache file 54 | .idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kameleo Local API Example Codes 2 | 3 | With [Kameleo](https://kameleo.io), you can easily create multiple virtual browser profiles to work with multiple accounts. It helps you hide your actual timezone, geolocation, language, IP address and creates natural browser fingerprints to prevent detection by anti-bot systems. Kameleo is compatible with [Selenium](https://www.selenium.dev/), [Playwright](https://playwright.dev/), and [Puppeteer](https://pptr.dev/) frameworks for automating web scraping tasks. This repository shows useful and easy to understand examples written in Node.js, Python and .NET Core (C#) about web scraping and automated browsing with Kameleo Client. 4 | 5 | ## Features 6 | 7 | - Stay completely undetected, so websites won’t be able to detect that you are using automation tools 8 | - Start unlimited number of profiles with different natural browser fingerprints 9 | - Use authenticated HTTP/SOCKS/SSH proxies in browsers 10 | - Create isolated browsing environments simultaneously 11 | - Use real browser profiles of Chrome, Firefox, Safari and Edge 12 | - Edit, Import or Export browser cookies 13 | - Modify WebRTC parameters 14 | - Modify Geolocation settings 15 | - Modify Timezone and Language settings 16 | - Modify WebGL fingerprint 17 | - Modify 2D Canvas fingerprint 18 | - Modify Navigator properties 19 | - Modify Screen resolution 20 | 21 | > _For an overview of automating with Kameleo and which plan you need to access these features, see our [pricing page](https://kameleo.io/pricing)._ 22 | 23 | ## How to start examples 24 | 25 | ### 1. Start the Kameleo.CLI on your computer 26 | 27 | ```powershell 28 | ./Kameleo.CLI email="your@email.com" password="Pa$$w0rd" 29 | ``` 30 | 31 | ### 2. Start the example code that you are interested in 32 | 33 | - For projects located in the `nodejs` folder you must run `npm install` and then `npm start`. 34 | - For projects located in the `python` folder you must run `pip install -r requirements.txt` and then `python app.py`. 35 | - For project located in the `dotnet-csharp` folder just open the .csproj file using Visual Studio 2019 or later. 36 | 37 | ### 3. Check out Kameleo Help Center 38 | 39 | If you are interested in more information about Kameleo, or have encountered an issue with using it, please check out our [Help Center](https://help.kameleo.io/). 40 | 41 | ### Examples index 42 | 43 | | Folder | Description | 44 | | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 45 | | automate_mobile_profiles_on_desktop | This code shows you how to emulate a mobile device in Chroma browser. And how to drive it with Selenium or any other automation framework. | 46 | | basic_profile_operations | Shows basic profile operations with the Kameleo API, like finding the right fingerprint, creating profiles, duplicating them, modifying their spoofing options, launching the browser. | 47 | | clean_workspace | Delete the profiles in your Kameleo Workspace. Useful when migrating to Kameleo 3, in particular. | 48 | | connect_with_playwright_to_chrome | This code shows how to start a Chromium-based browser in Kameleo and automate tasks using the [Playwright](https://playwright.dev/) framework. | 49 | | connect_with_playwright_to_firefox | This code illustrates how to start a Firefox in Kameleo and then automate actions using the [Playwright](https://playwright.dev/) framework. | 50 | | connect_with_puppeteer | This code illustrates how to start a Chromium based browser in Kameleo and then automate actions using the [Puppeteer](https://pptr.dev/) framework. | 51 | | connect_with_selenium | This code shows you how to launch a browser in Kameleo, perform actions using [Selenium](https://www.selenium.dev/) commands, and then close the browser. | 52 | | cookie_robot | Shows warming up the profile by visiting well-known sites so the browser has their cookies. This can make make the profile more trustworthy to other sites. | 53 | | manage_cookies | Kameleo allows you to edit, modify or create cookies with just a few lines of code. | 54 | | profile_export_import | This is a quick example of saving and loading profiles to/from .kameleo files on your computer. | 55 | | start_browser_with_additional_options | Check out this example if you want to pass command-line arguments or extra [Selenium](https://www.selenium.dev/) capabilities when starting a browser. | 56 | | start_with_proxy | Kameleo makes it easy to use any HTTP, SOCKS, or SSH proxy. Check out these few lines of code to see how. | 57 | | take_screenshot_with_puppeteer | Shows launching a Kameleo profile and taking a screenshot of a website using the [Puppeteer](https://pptr.dev/) framework. | 58 | | upgrade_profile | If you reuse virtual browser profiles and you would like to update the spoofed browser version you should follow this example. | 59 | 60 | - C# only 61 | - `file_upload_with_selenium` - Shows uploading a file to a website using the [Selenium](https://www.selenium.dev/) framework. 62 | - `modify_request_response_with_selenium` - Shows intercepting and modifying network communication by the browser using the [Selenium](https://www.selenium.dev/) framework. 63 | - JavaScript only 64 | - `commonjs` - Shows how to use the Kameleo API with CommonJS modules (other examples are ESM) 65 | -------------------------------------------------------------------------------- /dotnet-csharp/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | *screenshot*/*.png 7 | # User-specific files 8 | *.rsuser 9 | *.suo 10 | *.user 11 | *.userosscache 12 | *.sln.docstates 13 | 14 | # User-specific files (MonoDevelop/Xamarin Studio) 15 | *.userprefs 16 | 17 | # Mono auto generated files 18 | mono_crash.* 19 | 20 | # Build results 21 | [Dd]ebug/ 22 | [Dd]ebugPublic/ 23 | [Rr]elease/ 24 | [Rr]eleases/ 25 | x64/ 26 | x86/ 27 | [Ww][Ii][Nn]32/ 28 | [Aa][Rr][Mm]/ 29 | [Aa][Rr][Mm]64/ 30 | bld/ 31 | [Bb]in/ 32 | [Oo]bj/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd 364 | 365 | *.kameleo -------------------------------------------------------------------------------- /dotnet-csharp/Kameleo.LocalApi.Examples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.32112.339 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectWithSelenium", "connect_with_selenium\ConnectWithSelenium.csproj", "{3E86DFCA-EEA3-4085-BB6E-870CD06F0E02}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManageCookies", "manage_cookies\ManageCookies.csproj", "{3BBBBFC7-E24F-492F-883D-AE1DED165E22}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProfileExportImport", "profile_export_import\ProfileExportImport.csproj", "{64140277-D6A3-4827-8801-0F4148555AEA}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StartWithProxy", "start_with_proxy\StartWithProxy.csproj", "{AD3D25A3-9742-4EED-932F-15DE186FC03D}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StartBrowserWithAdditionalOptions", "start_browser_with_additional_options\StartBrowserWithAdditionalOptions.csproj", "{3D70BFC4-DB3D-4B51-AD19-4A25A3411930}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectWithPuppeteer", "connect_with_puppeteer\ConnectWithPuppeteer.csproj", "{2213577D-4BDA-4D0A-93E8-95423150DAC1}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectWithPlaywrightToFirefox", "connect_with_playwright_to_firefox\ConnectWithPlaywrightToFirefox.csproj", "{CA9128F3-05B9-4385-87EC-554C09E780F2}" 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConnectWithPlaywrightToChrome", "connect_with_playwright_to_chrome\ConnectWithPlaywrightToChrome.csproj", "{42C3E7B9-50A0-438C-A4C4-718FA24CBB5A}" 21 | EndProject 22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UpgradeProfile", "upgrade_profile\UpgradeProfile.csproj", "{268A15DD-A1FA-4AD8-BC35-BBADB9C7E735}" 23 | EndProject 24 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutomateMobileProfilesOnDesktop", "automate_mobile_profiles_on_desktop\AutomateMobileProfilesOnDesktop.csproj", "{7FDE0C07-9E77-466B-91C4-81B2FEC05806}" 25 | EndProject 26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CleanWorkspace", "clean_workspace\CleanWorkspace.csproj", "{CDAD9604-44AE-43FD-A91F-2E063787CF33}" 27 | EndProject 28 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicProfileOperations", "basic_profile_operations\BasicProfileOperations.csproj", "{1458F9BA-F89F-42E7-8D33-049141E22224}" 29 | EndProject 30 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileUploadWithSelenium", "file_upload_with_selenium\FileUploadWithSelenium.csproj", "{6AF1EF52-15DE-4B72-B18B-717D8285E188}" 31 | EndProject 32 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TakeScreenshotWithPuppeteer", "take_screenshot_with_puppeteer\TakeScreenshotWithPuppeteer.csproj", "{8EC194B0-465A-4A91-AC71-D9212EF32C0E}" 33 | EndProject 34 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CookieRobot", "cookie_robot\CookieRobot.csproj", "{219AB7E4-885E-4457-B0BC-DF154BCEF8BD}" 35 | EndProject 36 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModifyRequestResponseWithSelenium", "modify_request_response_with_selenium\ModifyRequestResponseWithSelenium.csproj", "{D1E4FBEF-BE8B-4B08-81A1-EB4ED6A61D13}" 37 | EndProject 38 | Global 39 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 40 | Debug|Any CPU = Debug|Any CPU 41 | Release|Any CPU = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 44 | {3E86DFCA-EEA3-4085-BB6E-870CD06F0E02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {3E86DFCA-EEA3-4085-BB6E-870CD06F0E02}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {3E86DFCA-EEA3-4085-BB6E-870CD06F0E02}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {3E86DFCA-EEA3-4085-BB6E-870CD06F0E02}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {3BBBBFC7-E24F-492F-883D-AE1DED165E22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {3BBBBFC7-E24F-492F-883D-AE1DED165E22}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {3BBBBFC7-E24F-492F-883D-AE1DED165E22}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {3BBBBFC7-E24F-492F-883D-AE1DED165E22}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {64140277-D6A3-4827-8801-0F4148555AEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {64140277-D6A3-4827-8801-0F4148555AEA}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {64140277-D6A3-4827-8801-0F4148555AEA}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {64140277-D6A3-4827-8801-0F4148555AEA}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {AD3D25A3-9742-4EED-932F-15DE186FC03D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {AD3D25A3-9742-4EED-932F-15DE186FC03D}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {AD3D25A3-9742-4EED-932F-15DE186FC03D}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {AD3D25A3-9742-4EED-932F-15DE186FC03D}.Release|Any CPU.Build.0 = Release|Any CPU 60 | {3D70BFC4-DB3D-4B51-AD19-4A25A3411930}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {3D70BFC4-DB3D-4B51-AD19-4A25A3411930}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {3D70BFC4-DB3D-4B51-AD19-4A25A3411930}.Release|Any CPU.ActiveCfg = Release|Any CPU 63 | {3D70BFC4-DB3D-4B51-AD19-4A25A3411930}.Release|Any CPU.Build.0 = Release|Any CPU 64 | {2213577D-4BDA-4D0A-93E8-95423150DAC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 65 | {2213577D-4BDA-4D0A-93E8-95423150DAC1}.Debug|Any CPU.Build.0 = Debug|Any CPU 66 | {2213577D-4BDA-4D0A-93E8-95423150DAC1}.Release|Any CPU.ActiveCfg = Release|Any CPU 67 | {2213577D-4BDA-4D0A-93E8-95423150DAC1}.Release|Any CPU.Build.0 = Release|Any CPU 68 | {CA9128F3-05B9-4385-87EC-554C09E780F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 69 | {CA9128F3-05B9-4385-87EC-554C09E780F2}.Debug|Any CPU.Build.0 = Debug|Any CPU 70 | {CA9128F3-05B9-4385-87EC-554C09E780F2}.Release|Any CPU.ActiveCfg = Release|Any CPU 71 | {CA9128F3-05B9-4385-87EC-554C09E780F2}.Release|Any CPU.Build.0 = Release|Any CPU 72 | {42C3E7B9-50A0-438C-A4C4-718FA24CBB5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 73 | {42C3E7B9-50A0-438C-A4C4-718FA24CBB5A}.Debug|Any CPU.Build.0 = Debug|Any CPU 74 | {42C3E7B9-50A0-438C-A4C4-718FA24CBB5A}.Release|Any CPU.ActiveCfg = Release|Any CPU 75 | {42C3E7B9-50A0-438C-A4C4-718FA24CBB5A}.Release|Any CPU.Build.0 = Release|Any CPU 76 | {268A15DD-A1FA-4AD8-BC35-BBADB9C7E735}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 77 | {268A15DD-A1FA-4AD8-BC35-BBADB9C7E735}.Debug|Any CPU.Build.0 = Debug|Any CPU 78 | {268A15DD-A1FA-4AD8-BC35-BBADB9C7E735}.Release|Any CPU.ActiveCfg = Release|Any CPU 79 | {268A15DD-A1FA-4AD8-BC35-BBADB9C7E735}.Release|Any CPU.Build.0 = Release|Any CPU 80 | {7FDE0C07-9E77-466B-91C4-81B2FEC05806}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 81 | {7FDE0C07-9E77-466B-91C4-81B2FEC05806}.Debug|Any CPU.Build.0 = Debug|Any CPU 82 | {7FDE0C07-9E77-466B-91C4-81B2FEC05806}.Release|Any CPU.ActiveCfg = Release|Any CPU 83 | {7FDE0C07-9E77-466B-91C4-81B2FEC05806}.Release|Any CPU.Build.0 = Release|Any CPU 84 | {CDAD9604-44AE-43FD-A91F-2E063787CF33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 85 | {CDAD9604-44AE-43FD-A91F-2E063787CF33}.Debug|Any CPU.Build.0 = Debug|Any CPU 86 | {CDAD9604-44AE-43FD-A91F-2E063787CF33}.Release|Any CPU.ActiveCfg = Release|Any CPU 87 | {CDAD9604-44AE-43FD-A91F-2E063787CF33}.Release|Any CPU.Build.0 = Release|Any CPU 88 | {1458F9BA-F89F-42E7-8D33-049141E22224}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 89 | {1458F9BA-F89F-42E7-8D33-049141E22224}.Debug|Any CPU.Build.0 = Debug|Any CPU 90 | {1458F9BA-F89F-42E7-8D33-049141E22224}.Release|Any CPU.ActiveCfg = Release|Any CPU 91 | {1458F9BA-F89F-42E7-8D33-049141E22224}.Release|Any CPU.Build.0 = Release|Any CPU 92 | {6AF1EF52-15DE-4B72-B18B-717D8285E188}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 93 | {6AF1EF52-15DE-4B72-B18B-717D8285E188}.Debug|Any CPU.Build.0 = Debug|Any CPU 94 | {6AF1EF52-15DE-4B72-B18B-717D8285E188}.Release|Any CPU.ActiveCfg = Release|Any CPU 95 | {6AF1EF52-15DE-4B72-B18B-717D8285E188}.Release|Any CPU.Build.0 = Release|Any CPU 96 | {8EC194B0-465A-4A91-AC71-D9212EF32C0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 97 | {8EC194B0-465A-4A91-AC71-D9212EF32C0E}.Debug|Any CPU.Build.0 = Debug|Any CPU 98 | {8EC194B0-465A-4A91-AC71-D9212EF32C0E}.Release|Any CPU.ActiveCfg = Release|Any CPU 99 | {8EC194B0-465A-4A91-AC71-D9212EF32C0E}.Release|Any CPU.Build.0 = Release|Any CPU 100 | {219AB7E4-885E-4457-B0BC-DF154BCEF8BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 101 | {219AB7E4-885E-4457-B0BC-DF154BCEF8BD}.Debug|Any CPU.Build.0 = Debug|Any CPU 102 | {219AB7E4-885E-4457-B0BC-DF154BCEF8BD}.Release|Any CPU.ActiveCfg = Release|Any CPU 103 | {219AB7E4-885E-4457-B0BC-DF154BCEF8BD}.Release|Any CPU.Build.0 = Release|Any CPU 104 | {D1E4FBEF-BE8B-4B08-81A1-EB4ED6A61D13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 105 | {D1E4FBEF-BE8B-4B08-81A1-EB4ED6A61D13}.Debug|Any CPU.Build.0 = Debug|Any CPU 106 | {D1E4FBEF-BE8B-4B08-81A1-EB4ED6A61D13}.Release|Any CPU.ActiveCfg = Release|Any CPU 107 | {D1E4FBEF-BE8B-4B08-81A1-EB4ED6A61D13}.Release|Any CPU.Build.0 = Release|Any CPU 108 | EndGlobalSection 109 | GlobalSection(SolutionProperties) = preSolution 110 | HideSolutionNode = FALSE 111 | EndGlobalSection 112 | GlobalSection(ExtensibilityGlobals) = postSolution 113 | SolutionGuid = {D60F09FB-E73A-451B-BA39-8811B7E782FE} 114 | EndGlobalSection 115 | EndGlobal 116 | -------------------------------------------------------------------------------- /dotnet-csharp/automate_mobile_profiles_on_desktop/AutomateMobileProfilesOnDesktop.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /dotnet-csharp/automate_mobile_profiles_on_desktop/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Kameleo.LocalApiClient; 5 | using Kameleo.LocalApiClient.Model; 6 | using OpenQA.Selenium; 7 | using OpenQA.Selenium.Chrome; 8 | using OpenQA.Selenium.Remote; 9 | 10 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 11 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 12 | { 13 | KameleoPort = 5050; 14 | } 15 | 16 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 17 | 18 | // Search for a mobile fingerprints 19 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync("mobile", "ios", "safari"); 20 | 21 | // Create a new profile with automatic recommended settings 22 | // Choose one of the fingerprints 23 | // Kameleo launches mobile profiles with our Chroma browser 24 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 25 | { 26 | Name = "automate mobile profiles on desktop example", 27 | }; 28 | 29 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 30 | 31 | // Start the profile 32 | await client.Profile.StartProfileAsync(profile.Id, new BrowserSettings() 33 | { 34 | AdditionalOptions = new List 35 | { 36 | // This allows you to click on elements using the cursor when emulating a touch screen in the browser. 37 | // If you leave this out, your script may time out after clicks and fail. 38 | new Preference("disableTouchEmulation", true), 39 | } 40 | }); 41 | 42 | // Connect to the running browser instance using WebDriver 43 | var uri = new Uri($"http://localhost:{KameleoPort}/webdriver"); 44 | var opts = new ChromeOptions(); 45 | opts.AddAdditionalOption("kameleo:profileId", profile.Id.ToString()); 46 | var webdriver = new RemoteWebDriver(uri, opts); 47 | webdriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(3); 48 | 49 | // Use any WebDriver command to drive the browser 50 | // and enjoy full protection from bot detection products 51 | webdriver.Navigate().GoToUrl("https://wikipedia.org"); 52 | webdriver.FindElement(By.Name("search")).SendKeys("Chameleon"); 53 | webdriver.FindElement(By.Name("search")).SendKeys(Keys.Enter); 54 | webdriver.FindElement(By.Id("content")); 55 | var title = webdriver.Title; 56 | Console.WriteLine($"The title is {title}"); 57 | 58 | await Task.Delay(TimeSpan.FromSeconds(5)); 59 | 60 | // Stop the browser by stopping the Kameleo profile 61 | await client.Profile.StopProfileAsync(profile.Id); 62 | -------------------------------------------------------------------------------- /dotnet-csharp/basic_profile_operations/BasicProfileOperations.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /dotnet-csharp/basic_profile_operations/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Kameleo.LocalApiClient; 4 | using Kameleo.LocalApiClient.Model; 5 | 6 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 7 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 8 | { 9 | KameleoPort = 5050; 10 | } 11 | 12 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 13 | 14 | // Search Chrome fingerprints 15 | // Possible deviceType value: desktop, mobile 16 | // Possible browserProduct value: chrome, firefox, edge, ... 17 | // Possible osFamily values: windows, macos, linux, android, ios 18 | // Examples of browserVersion values that limit the major version of the fingeprint: 135, >134, ... 19 | // You can use empty parameters as well, Kameleo provides recent and varied fingerprints by default 20 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync("desktop", "windows", "chrome", ">134"); 21 | 22 | Console.WriteLine("Available fingerprints:"); 23 | foreach (var fingerprint in fingerprints) 24 | { 25 | Console.WriteLine( 26 | $"{fingerprint.Os.Family} {fingerprint.Os.VarVersion} - {fingerprint.Browser.Product} {fingerprint.Browser.VarVersion}"); 27 | } 28 | 29 | // Select a random fingerprint 30 | var selectedFingerprint = fingerprints[Random.Shared.Next(0, fingerprints.Count - 1)]; 31 | 32 | Console.WriteLine( 33 | $"Selected fingerprint: {selectedFingerprint.Os.Family} {selectedFingerprint.Os.VarVersion} - " + 34 | $"{selectedFingerprint.Browser.Product} {selectedFingerprint.Browser.VarVersion}"); 35 | 36 | // Create a new profile with recommended settings using the selected Chrome fingerprints 37 | // You can setup here all of the profile options like WebGL, password manager and start page 38 | var createProfileRequest = new CreateProfileRequest(selectedFingerprint.Id) 39 | { 40 | Name = "create profile example", 41 | Language = "es-es", 42 | Webgl = WebglSpoofingType.Noise, 43 | WebglMeta = new (WebglMetaSpoofingType.Manual, 44 | new WebglMetaSpoofingOptions("Google Inc.", "ANGLE (Intel(R) HD Graphics 630 Direct3D11 vs_5_0 ps_5_0)")), 45 | PasswordManager = PasswordManagerType.Enabled, 46 | StartPage = "https://kameleo.io", 47 | }; 48 | 49 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 50 | 51 | Console.WriteLine($"Id of the created profile: {profile.Id}"); 52 | 53 | // Start the profile 54 | await client.Profile.StartProfileAsync(profile.Id); 55 | 56 | // Wait for 10 seconds 57 | await Task.Delay(10_000); 58 | 59 | // Stop the profile 60 | await client.Profile.StopProfileAsync(profile.Id); 61 | 62 | // Duplicate the previously created profile 63 | var duplicatedProfile = await client.Profile.DuplicateProfileAsync(profile.Id); 64 | 65 | Console.WriteLine($"Profile '{duplicatedProfile.Name}' is created"); 66 | 67 | // Change every property that you want to update on the duplicate profile 68 | // Others should be the same 69 | var updateProfileRequest = new UpdateProfileRequest() 70 | { 71 | Name = "duplicate profile example", 72 | WebglMeta = new WebglMetaChoice(WebglMetaSpoofingType.Automatic) 73 | }; 74 | 75 | // Send the update request and the response will be your updated profile 76 | duplicatedProfile = await client.Profile.UpdateProfileAsync(duplicatedProfile.Id, updateProfileRequest); 77 | 78 | // Start the profile 79 | await client.Profile.StartProfileAsync(duplicatedProfile.Id); 80 | 81 | // Wait for 10 seconds 82 | await Task.Delay(10_000); 83 | 84 | // Stop the profile 85 | await client.Profile.StopProfileAsync(duplicatedProfile.Id); 86 | 87 | // Delete original profile 88 | // Profiles need to be deleted explicitly becase they are persisted so they are available after restarting Kameleo 89 | await client.Profile.DeleteProfileAsync(profile.Id); 90 | -------------------------------------------------------------------------------- /dotnet-csharp/clean_workspace/CleanWorkspace.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /dotnet-csharp/clean_workspace/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Kameleo.LocalApiClient; 3 | 4 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 5 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 6 | { 7 | KameleoPort = 5050; 8 | } 9 | 10 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 11 | 12 | // List all existing profiles 13 | var profiles = await client.Profile.ListProfilesAsync(); 14 | 15 | // Delete profiles one by one 16 | foreach (var profile in profiles) 17 | { 18 | await client.Profile.DeleteProfileAsync(profile.Id); 19 | } 20 | 21 | Console.WriteLine($"{profiles.Count} profiles deleted."); 22 | -------------------------------------------------------------------------------- /dotnet-csharp/connect_with_playwright_to_chrome/ConnectWithPlaywrightToChrome.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /dotnet-csharp/connect_with_playwright_to_chrome/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Kameleo.LocalApiClient; 4 | using Kameleo.LocalApiClient.Model; 5 | using Microsoft.Playwright; 6 | 7 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 8 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 9 | { 10 | KameleoPort = 5050; 11 | } 12 | 13 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 14 | 15 | // Search Chrome fingerprints 16 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "chrome"); 17 | 18 | // Create a new profile with recommended settings 19 | // for browser fingerprint protection 20 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 21 | { 22 | Name = "connect with Playwright to Chrome example", 23 | }; 24 | 25 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 26 | 27 | // Start the Kameleo profile and connect with Playwright through CDP 28 | var browserWsEndpoint = $"ws://localhost:{KameleoPort}/playwright/{profile.Id}"; 29 | var playwright = await Playwright.CreateAsync(); 30 | var browser = await playwright.Chromium.ConnectOverCDPAsync(browserWsEndpoint); 31 | 32 | // It is recommended to work on the default context. 33 | // NOTE: We DO NOT recommend using multiple browser contexts, as this might interfere 34 | // with Kameleo's browser fingerprint modification features. 35 | var context = browser.Contexts[0]; 36 | var page = await context.NewPageAsync(); 37 | 38 | // Use any Playwright command to drive the browser 39 | // and enjoy full protection from bot detection products 40 | await page.GotoAsync("https://wikipedia.org"); 41 | await page.ClickAsync("[name=search]"); 42 | await page.Keyboard.TypeAsync("Chameleon"); 43 | await page.Keyboard.PressAsync("Enter"); 44 | 45 | // Wait for 5 seconds 46 | await Task.Delay(5_000); 47 | 48 | // Stop the browser by stopping the Kameleo profile 49 | await client.Profile.StopProfileAsync(profile.Id); 50 | -------------------------------------------------------------------------------- /dotnet-csharp/connect_with_playwright_to_firefox/ConnectWithPlaywrightToFirefox.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /dotnet-csharp/connect_with_playwright_to_firefox/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Threading.Tasks; 5 | using Kameleo.LocalApiClient; 6 | using Kameleo.LocalApiClient.Model; 7 | using Microsoft.Playwright; 8 | 9 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 10 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 11 | { 12 | KameleoPort = 5050; 13 | } 14 | 15 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 16 | 17 | // Search Firefox fingerprints 18 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "firefox"); 19 | 20 | // Create a new profile with recommended settings 21 | // for browser fingerprint protection 22 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 23 | { 24 | Name = "connect with Playwright to Firefox example", 25 | }; 26 | 27 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 28 | 29 | // Start the Kameleo profile and connect with Playwright 30 | var browserWsEndpoint = $"ws://localhost:{KameleoPort}/playwright/{profile.Id}"; 31 | 32 | // The Playwright framework is not designed to connect to already running 33 | // browsers. To overcome this limitation, a tool bundled with Kameleo, named 34 | // pw-bridge will bridge the communication gap between the running Firefox 35 | // instance and this playwright script. 36 | // The exact path to the bridge executable is subject to change. 37 | var pwBridgePath = Environment.GetEnvironmentVariable("PW_BRIDGE_PATH"); 38 | if (pwBridgePath is null && OperatingSystem.IsWindows()) 39 | { 40 | var localAppDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); 41 | pwBridgePath = Path.Combine(localAppDataFolder, "Programs", "Kameleo", "pw-bridge.exe"); 42 | } 43 | else if (pwBridgePath is null && OperatingSystem.IsMacOS()) 44 | { 45 | pwBridgePath = "/Applications/Kameleo.app/Contents/Resources/CLI/pw-bridge"; 46 | } 47 | 48 | var playwright = await Playwright.CreateAsync(); 49 | var browser = await playwright.Firefox.LaunchPersistentContextAsync("", new BrowserTypeLaunchPersistentContextOptions 50 | { 51 | ExecutablePath = pwBridgePath, 52 | Args = new List { $"-target {browserWsEndpoint}" }, 53 | ViewportSize = null, 54 | }); 55 | 56 | // Kameleo will open the a new page in the default browser context. 57 | // NOTE: We DO NOT recommend using multiple browser contexts, as this might interfere 58 | // with Kameleo's browser fingerprint modification features. 59 | var page = await browser.NewPageAsync(); 60 | 61 | // Use any Playwright command to drive the browser 62 | // and enjoy full protection from bot detection products 63 | await page.GotoAsync("https://wikipedia.org"); 64 | await page.ClickAsync("[name=search]"); 65 | await page.Keyboard.TypeAsync("Chameleon"); 66 | await page.Keyboard.PressAsync("Enter"); 67 | 68 | // Wait for 5 seconds 69 | await Task.Delay(5_000); 70 | 71 | // Stop the browser by stopping the Kameleo profile 72 | await client.Profile.StopProfileAsync(profile.Id); 73 | -------------------------------------------------------------------------------- /dotnet-csharp/connect_with_puppeteer/ConnectWithPuppeteer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /dotnet-csharp/connect_with_puppeteer/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Kameleo.LocalApiClient; 4 | using Kameleo.LocalApiClient.Model; 5 | using PuppeteerSharp; 6 | 7 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 8 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 9 | { 10 | KameleoPort = 5050; 11 | } 12 | 13 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 14 | 15 | // Search Chrome fingerprints 16 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "chrome"); 17 | 18 | // Create a new profile with recommended settings 19 | // for browser fingerprint protection 20 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 21 | { 22 | Name = "connect with Puppeteer example", 23 | }; 24 | 25 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 26 | 27 | // Start the Kameleo profile and connect through CDP 28 | var browserWsEndpoint = $"ws://localhost:{KameleoPort}/puppeteer/{profile.Id}"; 29 | var browser = await Puppeteer.ConnectAsync(new ConnectOptions 30 | { 31 | BrowserWSEndpoint = browserWsEndpoint, 32 | DefaultViewport = null 33 | }); 34 | var page = await browser.NewPageAsync(); 35 | 36 | // Use any Puppeteer command to drive the browser 37 | // and enjoy full protection from bot detection products 38 | await page.GoToAsync("https://wikipedia.org"); 39 | await page.ClickAsync("[name=search]"); 40 | await page.Keyboard.TypeAsync("Chameleon"); 41 | await page.Keyboard.PressAsync("Enter"); 42 | 43 | // Wait for 5 seconds 44 | await Task.Delay(5_000); 45 | 46 | // Stop the browser by stopping the Kameleo profile 47 | await client.Profile.StopProfileAsync(profile.Id); 48 | -------------------------------------------------------------------------------- /dotnet-csharp/connect_with_selenium/ConnectWithSelenium.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /dotnet-csharp/connect_with_selenium/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Kameleo.LocalApiClient; 3 | using Kameleo.LocalApiClient.Model; 4 | using OpenQA.Selenium; 5 | using OpenQA.Selenium.Chrome; 6 | using OpenQA.Selenium.Remote; 7 | 8 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 9 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 10 | { 11 | KameleoPort = 5050; 12 | } 13 | 14 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 15 | 16 | // Search Chrome fingerprints 17 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "chrome"); 18 | 19 | // Create a new profile with recommended settings 20 | // for browser fingerprint protection 21 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 22 | { 23 | Name = "connect to Selenium example", 24 | }; 25 | 26 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 27 | 28 | // Start the Kameleo profile and connect using WebDriver protocol 29 | var uri = new Uri($"http://localhost:{KameleoPort}/webdriver"); 30 | var opts = new ChromeOptions(); 31 | opts.AddAdditionalOption("kameleo:profileId", profile.Id.ToString()); 32 | var webdriver = new RemoteWebDriver(uri, opts); 33 | webdriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(3); 34 | 35 | // Use any WebDriver command to drive the browser 36 | // and enjoy full protection from bot detection products 37 | webdriver.Navigate().GoToUrl("https://wikipedia.org"); 38 | webdriver.FindElement(By.Name("search")).SendKeys("Chameleon"); 39 | webdriver.FindElement(By.Name("search")).SendKeys(Keys.Enter); 40 | webdriver.FindElement(By.Id("content")); 41 | var title = webdriver.Title; 42 | Console.WriteLine($"The title is {title}"); 43 | 44 | // Stop the browser by stopping the Kameleo profile 45 | await client.Profile.StopProfileAsync(profile.Id); 46 | -------------------------------------------------------------------------------- /dotnet-csharp/cookie_robot/CookieRobot.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /dotnet-csharp/cookie_robot/Program.cs: -------------------------------------------------------------------------------- 1 | using Kameleo.LocalApiClient; 2 | using Kameleo.LocalApiClient.Model; 3 | using OpenQA.Selenium.Firefox; 4 | using OpenQA.Selenium.Remote; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Threading.Tasks; 8 | 9 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 10 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 11 | { 12 | KameleoPort = 5050; 13 | } 14 | 15 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 16 | 17 | // Search a fingerprint 18 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "firefox"); 19 | 20 | // Create a new profile with recommended settings 21 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 22 | { 23 | Name = "cookie robot example", 24 | }; 25 | 26 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 27 | 28 | // Start the Kameleo profile and connect to it using WebDriver protocol 29 | var uri = new Uri($"http://localhost:{KameleoPort}/webdriver"); 30 | var opts = new FirefoxOptions(); 31 | opts.AddAdditionalOption("kameleo:profileId", profile.Id.ToString()); 32 | var webdriver = new RemoteWebDriver(uri, opts); 33 | 34 | var allSites = new List 35 | { 36 | "instagram.com", 37 | "linkedin.com", 38 | "ebay.com", 39 | "pinterest.com", 40 | "reddit.com", 41 | "cnn.com", 42 | "bbc.co.uk", 43 | "nytimes.com", 44 | "reuters.com", 45 | "theguardian.com", 46 | "foxnews.com" 47 | }; 48 | 49 | // Select sites to collect cookies from 50 | var sitesToVisit = new List(); 51 | while (sitesToVisit.Count < 5) 52 | { 53 | var rndIndex = Random.Shared.Next(0, allSites.Count - 1); 54 | var site = allSites[rndIndex]; 55 | 56 | if (!sitesToVisit.Contains(site)) 57 | { 58 | sitesToVisit.Add(site); 59 | } 60 | } 61 | 62 | // Warm up profile by visiting the randomly selected sites 63 | foreach (var site in sitesToVisit) 64 | { 65 | // Navigate to the site 66 | webdriver.Navigate().GoToUrl($"https://{site}"); 67 | 68 | // Wait for some random time 69 | await Task.Delay(Random.Shared.Next(5_000, 15_000)); 70 | } 71 | 72 | // Stop the profile 73 | await client.Profile.StopProfileAsync(profile.Id); 74 | -------------------------------------------------------------------------------- /dotnet-csharp/file_upload_with_selenium/FileUploadWithSelenium.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Always 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /dotnet-csharp/file_upload_with_selenium/Program.cs: -------------------------------------------------------------------------------- 1 | using Kameleo.LocalApiClient; 2 | using Kameleo.LocalApiClient.Model; 3 | using OpenQA.Selenium; 4 | using OpenQA.Selenium.Chrome; 5 | using OpenQA.Selenium.Remote; 6 | using OpenQA.Selenium.Support.UI; 7 | using System; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Threading.Tasks; 11 | 12 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 13 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 14 | { 15 | KameleoPort = 5050; 16 | } 17 | 18 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 19 | 20 | // Search Chrome fingerprints 21 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "chrome"); 22 | 23 | // Create a new profile with recommended settings 24 | // for browser fingerprint protection 25 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 26 | { 27 | Name = "file upload example", 28 | }; 29 | 30 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 31 | 32 | // Start the Kameleo profile and connect using WebDriver protocol 33 | var uri = new Uri($"http://localhost:{KameleoPort}/webdriver"); 34 | var opts = new ChromeOptions(); 35 | opts.AddAdditionalOption("kameleo:profileId", profile.Id.ToString()); 36 | var webdriver = new RemoteWebDriver(uri, opts); 37 | 38 | // Open uplad site 39 | webdriver.Url = "https://the-internet.herokuapp.com/upload"; 40 | await Task.Delay(3_000); 41 | 42 | // Upload file 43 | var filePath = Path.Combine(Environment.CurrentDirectory, "kameleo.png"); 44 | var fileInput = webdriver.FindElementByCssSelector("input[type=file]"); 45 | fileInput.SendKeys(filePath); 46 | webdriver.FindElementById("file-submit").Click(); 47 | 48 | // Check file upload success 49 | var fileNameElement = webdriver.FindElementById("uploaded-files"); 50 | Console.WriteLine("uploaded file name: " + fileNameElement.Text); 51 | 52 | await Task.Delay(5_000); 53 | 54 | // Stop the browser by stopping the Kameleo profile 55 | await client.Profile.StopProfileAsync(profile.Id); 56 | -------------------------------------------------------------------------------- /dotnet-csharp/file_upload_with_selenium/kameleo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kameleo-io/local-api-examples/d93efa68ec042f2bd718470f8c993e90f118e446/dotnet-csharp/file_upload_with_selenium/kameleo.png -------------------------------------------------------------------------------- /dotnet-csharp/manage_cookies/ManageCookies.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /dotnet-csharp/manage_cookies/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Kameleo.LocalApiClient; 5 | using Kameleo.LocalApiClient.Model; 6 | using OpenQA.Selenium.Firefox; 7 | using OpenQA.Selenium.Remote; 8 | 9 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 10 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 11 | { 12 | KameleoPort = 5050; 13 | } 14 | 15 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 16 | 17 | // Search a fingerprint 18 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "chrome"); 19 | 20 | // Create a new profile with recommended settings 21 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 22 | { 23 | Name = "manage cookies example", 24 | }; 25 | 26 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 27 | 28 | // Start the Kameleo profile and connect to it using WebDriver protocol 29 | var uri = new Uri($"http://localhost:{KameleoPort}/webdriver"); 30 | var opts = new FirefoxOptions(); 31 | opts.AddAdditionalOption("kameleo:profileId", profile.Id.ToString()); 32 | var webdriver = new RemoteWebDriver(uri, opts); 33 | 34 | 35 | // Navigate to a site which give you cookies 36 | webdriver.Navigate().GoToUrl("https://www.nytimes.com"); 37 | await Task.Delay(5_000); 38 | 39 | webdriver.Navigate().GoToUrl("https://whoer.net"); 40 | await Task.Delay(5_000); 41 | 42 | webdriver.Navigate().GoToUrl("https://www.youtube.com"); 43 | await Task.Delay(5_000); 44 | 45 | // Stop the profile 46 | await client.Profile.StopProfileAsync(profile.Id); 47 | 48 | // You can list all of your cookies 49 | var cookieList = await client.Cookie.ListCookiesAsync(profile.Id); 50 | Console.WriteLine("The cookies of the profile: "); 51 | foreach (var cookie in cookieList) 52 | { 53 | Console.WriteLine($"{cookie.Domain}, {cookie.Path}, {cookie.Name}"); 54 | } 55 | 56 | // You can modify cookie or you can add new 57 | var newCookie = cookieList[0]; 58 | newCookie.Value = "123"; 59 | var cookiesArray = new List { new CookieRequest(newCookie) }; 60 | await client.Cookie.AddCookiesAsync(profile.Id, cookiesArray); 61 | 62 | // You can delete all cookies of the profile 63 | await client.Cookie.DeleteCookiesAsync(profile.Id); 64 | -------------------------------------------------------------------------------- /dotnet-csharp/modify_request_response_with_selenium/ModifyRequestResponseWithSelenium.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Always 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /dotnet-csharp/modify_request_response_with_selenium/Program.cs: -------------------------------------------------------------------------------- 1 | using Kameleo.LocalApiClient; 2 | using Kameleo.LocalApiClient.Model; 3 | using OpenQA.Selenium; 4 | using OpenQA.Selenium.Chrome; 5 | using OpenQA.Selenium.Remote; 6 | using System; 7 | using System.IO; 8 | using System.Threading.Tasks; 9 | 10 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 11 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 12 | { 13 | KameleoPort = 5050; 14 | } 15 | 16 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 17 | 18 | // Search Chrome fingerprints 19 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "chrome"); 20 | 21 | // Create a new profile with recommended settings 22 | // for browser fingerprint protection 23 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 24 | { 25 | Name = "modify request response example", 26 | }; 27 | 28 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 29 | 30 | // Start the Kameleo profile and connect using WebDriver protocol 31 | var uri = new Uri($"http://localhost:{KameleoPort}/webdriver"); 32 | var opts = new ChromeOptions(); 33 | opts.AddAdditionalOption("kameleo:profileId", profile.Id.ToString()); 34 | var webdriver = new RemoteWebDriver(uri, opts); 35 | 36 | // Set up network interceptor 37 | var interceptor = webdriver.Manage().Network; 38 | interceptor.NetworkRequestSent += Interceptor_NetworkRequestSent; 39 | interceptor.NetworkResponseReceived += Interceptor_NetworkResponseReceived; 40 | 41 | // Set up redirect from main to French home page 42 | interceptor.AddRequestHandler(new NetworkRequestHandler 43 | { 44 | RequestMatcher = request => request.Url.Trim('/') == "https://www.wikipedia.org", 45 | RequestTransformer = request => 46 | { 47 | Console.WriteLine($"Changing url"); 48 | request.Url = "https://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Accueil_principal"; 49 | return request; 50 | } 51 | }); 52 | 53 | // Set up replacing wikipedia's logo with that of Kameleo 54 | interceptor.AddRequestHandler(new NetworkRequestHandler 55 | { 56 | RequestMatcher = request => request.Url.Contains("wikipedia-wordmark-fr.svg"), 57 | ResponseSupplier = request => 58 | { 59 | var response = new HttpResponseData 60 | { 61 | StatusCode = 200, 62 | Content = new HttpResponseContent(File.ReadAllBytes("kameleo.svg")), 63 | Url = request.Url, 64 | RequestId = request.RequestId 65 | }; 66 | response.Headers.Add("Content-Type", "image/svg+xml"); 67 | 68 | return response; 69 | } 70 | }); 71 | 72 | await interceptor.StartMonitoring(); 73 | 74 | // Navigate to the main wikipedia home page and observe that the French one is loaded 75 | webdriver.Navigate().GoToUrl("https://www.wikipedia.org/"); 76 | 77 | await Task.Delay(10_000); 78 | 79 | await interceptor.StopMonitoring(); 80 | 81 | // Stop the browser by stopping the Kameleo profile 82 | await client.Profile.StopProfileAsync(profile.Id); 83 | 84 | void Interceptor_NetworkRequestSent(object sender, NetworkRequestSentEventArgs e) 85 | { 86 | Console.WriteLine($"[{e.RequestMethod}] {e.RequestUrl}"); 87 | } 88 | 89 | void Interceptor_NetworkResponseReceived(object sender, NetworkResponseReceivedEventArgs e) 90 | { 91 | Console.WriteLine($"[{e.ResponseStatusCode}] {e.ResponseUrl}" ); 92 | } 93 | -------------------------------------------------------------------------------- /dotnet-csharp/modify_request_response_with_selenium/kameleo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /dotnet-csharp/profile_export_import/ProfileExportImport.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | ProfileExportLoad 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /dotnet-csharp/profile_export_import/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using Kameleo.LocalApiClient; 5 | using Kameleo.LocalApiClient.Model; 6 | 7 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 8 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 9 | { 10 | KameleoPort = 5050; 11 | } 12 | 13 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 14 | 15 | // Search a fingerprint 16 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop"); 17 | 18 | // Create a new profile with recommended settings 19 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 20 | { 21 | Name = "profile export import example", 22 | }; 23 | 24 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 25 | 26 | // export the profile to a given path 27 | var exportPath = Path.Combine(Environment.CurrentDirectory, "test.kameleo"); 28 | var result = await client.Profile.ExportProfileAsync(profile.Id, new ExportProfileRequest(exportPath)); 29 | Console.WriteLine("Profile has been exported to " + exportPath); 30 | 31 | // You have to delete this profile if you want to import back 32 | await client.Profile.DeleteProfileAsync(profile.Id); 33 | 34 | // import the profile from the given url 35 | profile = await client.Profile.ImportProfileAsync( 36 | new ImportProfileRequest(Path.Combine(Environment.CurrentDirectory, "test.kameleo"))); 37 | 38 | // Start the profile 39 | await client.Profile.StartProfileAsync(profile.Id); 40 | 41 | // Wait for 10 seconds 42 | await Task.Delay(10_000); 43 | 44 | // Stop the profile 45 | await client.Profile.StopProfileAsync(profile.Id); 46 | -------------------------------------------------------------------------------- /dotnet-csharp/start_browser_with_additional_options/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Kameleo.LocalApiClient; 5 | using Kameleo.LocalApiClient.Model; 6 | 7 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 8 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 9 | { 10 | KameleoPort = 5050; 11 | } 12 | 13 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 14 | 15 | // Search Chrome fingerprints 16 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "chrome"); 17 | 18 | // Create a new profile with recommended settings 19 | // Choose one of the Chrome fingerprints 20 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 21 | { 22 | Name = "start browser with additional options example", 23 | }; 24 | 25 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 26 | 27 | // Provide additional settings for the webdriver when starting the browser 28 | // Use this command to customize the browser process by adding command-line arguments 29 | // like '--mute-audio' or '--start-maximized' 30 | // or modify the native profile settings when starting the browser 31 | 32 | // start the browser with the --mute-audio command line argument 33 | await client.Profile.StartProfileAsync(profile.Id, new BrowserSettings 34 | { 35 | Arguments = new List { "mute-audio" } 36 | }); 37 | 38 | // Wait for 10 seconds 39 | await Task.Delay(10_000); 40 | 41 | // Stop the profile 42 | await client.Profile.StopProfileAsync(profile.Id); 43 | 44 | // start the browser with an additional Selenum option 45 | await client.Profile.StartProfileAsync(profile.Id, new BrowserSettings 46 | { 47 | AdditionalOptions = new List { new("pageLoadStrategy", "eager") } 48 | }); 49 | 50 | // Wait for 10 seconds 51 | await Task.Delay(10_000); 52 | 53 | // Stop the profile 54 | await client.Profile.StopProfileAsync(profile.Id); 55 | 56 | // start the browser and also set a Chrome preference 57 | await client.Profile.StartProfileAsync(profile.Id, new BrowserSettings 58 | { 59 | Preferences = new List { new("profile.managed_default_content_settings.images", 2), } 60 | }); 61 | 62 | // Wait for 10 seconds 63 | await Task.Delay(10_000); 64 | 65 | // Stop the profile 66 | await client.Profile.StopProfileAsync(profile.Id); 67 | -------------------------------------------------------------------------------- /dotnet-csharp/start_browser_with_additional_options/StartBrowserWithAdditionalOptions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /dotnet-csharp/start_with_proxy/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Kameleo.LocalApiClient; 4 | using Kameleo.LocalApiClient.Model; 5 | 6 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 7 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 8 | { 9 | KameleoPort = 5050; 10 | } 11 | 12 | // Read proxy settings from environment variables or from code 13 | var proxyHost = Environment.GetEnvironmentVariable("PROXY_HOST") ?? ""; 14 | var proxyUsername = Environment.GetEnvironmentVariable("PROXY_USERNAME") ?? ""; 15 | var proxyPassword = Environment.GetEnvironmentVariable("PROXY_PASSWORD") ?? ""; 16 | if (!int.TryParse(Environment.GetEnvironmentVariable("PROXY_PORT"), out var proxyPort)) 17 | { 18 | proxyPort = 1080; 19 | } 20 | 21 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 22 | 23 | // Search Firefox fingerprints 24 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync("desktop", null, "firefox"); 25 | 26 | // Create a new profile with recommended settings 27 | // Choose one of the Firefox fingerprints 28 | // You can set your proxy up in the setProxy method 29 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 30 | { 31 | Name = "start with proxy example", 32 | Proxy = new (ProxyConnectionType.Socks5, new Server(proxyHost, proxyPort, proxyUsername, proxyPassword)) 33 | }; 34 | 35 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 36 | 37 | // Start the profile 38 | await client.Profile.StartProfileAsync(profile.Id); 39 | 40 | // Wait for 10 seconds 41 | await Task.Delay(10_000); 42 | 43 | // Stop the profile 44 | await client.Profile.StopProfileAsync(profile.Id); 45 | -------------------------------------------------------------------------------- /dotnet-csharp/start_with_proxy/StartWithProxy.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /dotnet-csharp/take_screenshot_with_puppeteer/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Kameleo.LocalApiClient; 4 | using Kameleo.LocalApiClient.Model; 5 | using PuppeteerSharp; 6 | 7 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 8 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 9 | { 10 | KameleoPort = 5050; 11 | } 12 | 13 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 14 | 15 | // Search Chrome fingerprints 16 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "chrome"); 17 | 18 | // Create a new profile with recommended settings 19 | // for browser fingerprint protection 20 | var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) 21 | { 22 | Name = "take screenshot example", 23 | }; 24 | 25 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 26 | 27 | // Start the Kameleo profile and connect through CDP 28 | var browserWsEndpoint = $"ws://localhost:{KameleoPort}/puppeteer/{profile.Id}"; 29 | var browser = await Puppeteer.ConnectAsync(new ConnectOptions 30 | { 31 | BrowserWSEndpoint = browserWsEndpoint, 32 | DefaultViewport = null 33 | }); 34 | var page = await browser.NewPageAsync(); 35 | 36 | // Open a random page from wikipedia 37 | await page.GoToAsync("https://en.wikipedia.org/wiki/Special:Random", WaitUntilNavigation.DOMContentLoaded); 38 | 39 | var targetFile = Path.Combine(Environment.CurrentDirectory, Path.ChangeExtension(Path.GetRandomFileName(), ".png")); 40 | 41 | // Take screenshot 42 | await page.ScreenshotAsync(targetFile, new ScreenshotOptions { Type = ScreenshotType.Png }); 43 | 44 | Console.WriteLine(targetFile); 45 | 46 | // Stop the browser by stopping the Kameleo profile 47 | await client.Profile.StopProfileAsync(profile.Id); 48 | -------------------------------------------------------------------------------- /dotnet-csharp/take_screenshot_with_puppeteer/TakeScreenshotWithPuppeteer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /dotnet-csharp/upgrade_profile/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using Kameleo.LocalApiClient; 5 | using Kameleo.LocalApiClient.Model; 6 | 7 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 8 | if (!int.TryParse(Environment.GetEnvironmentVariable("KAMELEO_PORT"), out var KameleoPort)) 9 | { 10 | KameleoPort = 5050; 11 | } 12 | 13 | var client = new KameleoLocalApiClient(new Uri($"http://localhost:{KameleoPort}")); 14 | 15 | // Search for a Desktop fingerprint with Windows OS and Chrome browser 16 | var fingerprints = await client.Fingerprint.SearchFingerprintsAsync("desktop", "windows", "chrome"); 17 | 18 | // Find a fingerprint with the oldest available version of chrome 19 | var fingerprint = fingerprints.OrderBy(preview => preview.Browser.Major).First(); 20 | 21 | // Create a new profile with recommended settings 22 | // Choose one of the fingerprints 23 | var createProfileRequest = new CreateProfileRequest(fingerprint.Id) 24 | { 25 | Name = "upgrade profiles example", 26 | }; 27 | 28 | var profile = await client.Profile.CreateProfileAsync(createProfileRequest); 29 | 30 | Console.WriteLine( 31 | $"Profile's browser before update is: {profile.Fingerprint.Browser.Product} {profile.Fingerprint.Browser.VarVersion}"); 32 | 33 | // The fingerprint’s browser version will be updated if there is any available on our servers 34 | profile = await client.Profile.UpgradeProfileKernelAsync(profile.Id); 35 | Console.WriteLine( 36 | $"Profile's browser after update is: {profile.Fingerprint.Browser.Product} {profile.Fingerprint.Browser.VarVersion}"); 37 | 38 | // Start the profile 39 | await client.Profile.StartProfileAsync(profile.Id); 40 | 41 | // Wait for 5 seconds 42 | await Task.Delay(5_000); 43 | 44 | // Stop the profile 45 | await client.Profile.StopProfileAsync(profile.Id); 46 | -------------------------------------------------------------------------------- /dotnet-csharp/upgrade_profile/UpgradeProfile.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /nodejs/.gitignore: -------------------------------------------------------------------------------- 1 | *screenshot*/*.png 2 | 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | lerna-debug.log* 10 | 11 | # Diagnostic reports (https://nodejs.org/api/report.html) 12 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 13 | 14 | # Runtime data 15 | pids 16 | *.pid 17 | *.seed 18 | *.pid.lock 19 | 20 | # Directory for instrumented libs generated by jscoverage/JSCover 21 | lib-cov 22 | 23 | # Coverage directory used by tools like istanbul 24 | coverage 25 | *.lcov 26 | 27 | # nyc test coverage 28 | .nyc_output 29 | 30 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 31 | .grunt 32 | 33 | # Bower dependency directory (https://bower.io/) 34 | bower_components 35 | 36 | # node-waf configuration 37 | .lock-wscript 38 | 39 | # Compiled binary addons (https://nodejs.org/api/addons.html) 40 | build/Release 41 | 42 | # Dependency directories 43 | node_modules/ 44 | jspm_packages/ 45 | 46 | # Snowpack dependency directory (https://snowpack.dev/) 47 | web_modules/ 48 | 49 | # TypeScript cache 50 | *.tsbuildinfo 51 | 52 | # Optional npm cache directory 53 | .npm 54 | .npmrc 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Microbundle cache 60 | .rpt2_cache/ 61 | .rts2_cache_cjs/ 62 | .rts2_cache_es/ 63 | .rts2_cache_umd/ 64 | 65 | # Optional REPL history 66 | .node_repl_history 67 | 68 | # Output of 'npm pack' 69 | *.tgz 70 | 71 | # Yarn Integrity file 72 | .yarn-integrity 73 | 74 | # dotenv environment variables file 75 | .env 76 | .env.test 77 | 78 | # parcel-bundler cache (https://parceljs.org/) 79 | .cache 80 | .parcel-cache 81 | 82 | # Next.js build output 83 | .next 84 | out 85 | 86 | # Nuxt.js build / generate output 87 | .nuxt 88 | dist 89 | 90 | # Gatsby files 91 | .cache/ 92 | # Comment in the public line in if your project uses Gatsby and not Next.js 93 | # https://nextjs.org/blog/next-9-1#public-directory-support 94 | # public 95 | 96 | # vuepress build output 97 | .vuepress/dist 98 | 99 | # Serverless directories 100 | .serverless/ 101 | 102 | # FuseBox cache 103 | .fusebox/ 104 | 105 | # DynamoDB Local files 106 | .dynamodb/ 107 | 108 | # TernJS port file 109 | .tern-port 110 | 111 | # Stores VSCode versions used for testing VSCode extensions 112 | .vscode-test 113 | 114 | # yarn v2 115 | .yarn/cache 116 | .yarn/unplugged 117 | .yarn/build-state.yml 118 | .yarn/install-state.gz 119 | .pnp.* 120 | 121 | .vscode 122 | *.kameleo -------------------------------------------------------------------------------- /nodejs/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "all", 3 | "tabWidth": 2, 4 | "printWidth": 140, 5 | "endOfLine": "auto", 6 | "overrides": [ 7 | { 8 | "files": ["*.ts", "*.js", "*.mjs"], 9 | "options": { "tabWidth": 4 } 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /nodejs/automate_mobile_profiles_on_desktop/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import { Builder, By, Key, until } from "selenium-webdriver"; 3 | 4 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 5 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 6 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 7 | 8 | // Initialize the Kameleo client 9 | const client = new KameleoLocalApiClient({ 10 | basePath: kameleoCliUri, 11 | }); 12 | 13 | // Search for mobile fingerprints that match specific criteria 14 | // In this example, we are looking for iOS mobile profiles with Safari browser 15 | const fingerprints = await client.fingerprint.searchFingerprints("mobile", "ios", "safari"); 16 | 17 | // Create a new profile with automatic recommended settings 18 | // Choose one of the fingerprints 19 | // Kameleo launches mobile profiles with our Chroma browser 20 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 21 | const createProfileRequest = { 22 | fingerprintId: fingerprints[0].id, 23 | name: "automate mobile profiles on desktop example", 24 | }; 25 | const profile = await client.profile.createProfile(createProfileRequest); 26 | 27 | // Start the newly created profile 28 | // We disable touch emulation so that we can click on elements when emulating a mobile profile 29 | await client.profile.startProfile(profile.id, { 30 | additionalOptions: [ 31 | { 32 | key: "disableTouchEmulation", 33 | value: true, 34 | }, 35 | ], 36 | }); 37 | 38 | // Build the WebDriver for automating the mobile profile 39 | // Configure it to use Kameleo WebDriver server 40 | const builder = new Builder().usingServer(`${kameleoCliUri}/webdriver`).withCapabilities({ 41 | "kameleo:profileId": profile.id, 42 | browserName: "Kameleo", 43 | }); 44 | const webdriver = await builder.build(); 45 | 46 | // Automate the browser to perform a Wikipedia search and print the page title 47 | await webdriver.get("https://wikipedia.org"); 48 | await webdriver.findElement(By.name("search")).sendKeys("Chameleon", Key.ENTER); 49 | await webdriver.wait(until.elementLocated(By.id("content"))); 50 | const title = await webdriver.getTitle(); 51 | console.log(`The title is ${title}`); 52 | 53 | // Wait for 5 seconds 54 | await webdriver.sleep(5000); 55 | 56 | // Stop the browser by stopping the Kameleo profile 57 | await client.profile.stopProfile(profile.id); 58 | -------------------------------------------------------------------------------- /nodejs/automate_mobile_profiles_on_desktop/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "automate_mobile_profiles_on_desktop", 3 | "description": "This example uses the Kameleo Local API to create a mobile browser profile emulating an iOS device with Safari, then automates it using Selenium WebDriver to perform a Google search for 'Kameleo' and prints the page title.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/basic_profile_operations/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import randomInteger from "random-int"; 3 | import { setTimeout } from "timers/promises"; 4 | 5 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 6 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 7 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 8 | 9 | // Initialize the Kameleo client 10 | const client = new KameleoLocalApiClient({ 11 | basePath: kameleoCliUri, 12 | }); 13 | 14 | // Search Chrome fingerprints 15 | // Possible deviceType value: desktop, mobile 16 | // Possible browserProduct value: chrome, firefox, edge, ... 17 | // Possible osFamily values: windows, macos, linux, android, ios 18 | // Examples of browserVersion values that limit the major version of the fingeprint: 135, >134, ... 19 | // You can use empty parameters as well, Kameleo provides recent and varied fingerprints by default 20 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", "windows", "chrome", ">134"); 21 | 22 | // Create a new profile with recommended settings 23 | // Choose one of the Chrome fingerprints 24 | // You can setup here all of the profile options like WebGL, password manager and start page 25 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 26 | const createProfileRequest = { 27 | fingerprintId: fingerprints[randomInteger(fingerprints.length - 1)].id, 28 | name: "create profile example", 29 | language: "es-es", 30 | webgl: "noise", 31 | webglMeta: { 32 | value: "manual", 33 | extra: { 34 | vendor: "Google Inc.", 35 | renderer: "ANGLE (Intel(R) HD Graphics 630 Direct3D11 vs_5_0 ps_5_0)", 36 | }, 37 | }, 38 | passwordManager: "enabled", 39 | startPage: "https://kameleo.io", 40 | }; 41 | const profile = await client.profile.createProfile(createProfileRequest); 42 | 43 | // Start the profile 44 | await client.profile.startProfile(profile.id); 45 | 46 | // Wait for 10 seconds 47 | await setTimeout(10_000); 48 | 49 | // Stop the profile 50 | await client.profile.stopProfile(profile.id); 51 | 52 | let duplicatedProfile = await client.profile.duplicateProfile(profile.id); 53 | console.log(`Profile '${duplicatedProfile.name}' is just created`); 54 | 55 | // Change every property that you want to update on the duplicated profile 56 | // Send the update request and the response will be your updated profile 57 | duplicatedProfile = await client.profile.updateProfile(duplicatedProfile.id, { 58 | name: "duplicate profile example", 59 | }); 60 | 61 | // Start the profile 62 | await client.profile.startProfile(duplicatedProfile.id); 63 | 64 | // Wait for 10 seconds 65 | await setTimeout(10_000); 66 | 67 | // Stop the profile 68 | await client.profile.stopProfile(duplicatedProfile.id); 69 | 70 | // Delete original profile 71 | // Profiles need to be deleted explicitly becase they are persisted so they are available after restarting Kameleo 72 | await client.profile.deleteProfile(profile.id); 73 | -------------------------------------------------------------------------------- /nodejs/basic_profile_operations/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "basic_profile_operations", 3 | "description": "Shows basic profile operations with the Kameleo API, like finding the right fingerprint, creating profiles, duplicating them, modifying their spoofing options, launching the browser", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/clean_workspace/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | 3 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 4 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 5 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 6 | 7 | // Initialize the Kameleo client 8 | const client = new KameleoLocalApiClient({ 9 | basePath: kameleoCliUri, 10 | }); 11 | 12 | const profiles = await client.profile.listProfiles(); 13 | 14 | for (const profile of profiles) { 15 | console.log(profile.name); 16 | await client.profile.deleteProfile(profile.id); 17 | } 18 | 19 | console.log(`${profiles.length} profiles deleted.`); 20 | -------------------------------------------------------------------------------- /nodejs/clean_workspace/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "clean_workspace", 3 | "description": "Delete the profiles in your Kameleo Workspace.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/commonjs/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-require-imports */ 2 | const { KameleoLocalApiClient } = require("@kameleo/local-api-client"); 3 | const { setTimeout } = require("timers/promises"); 4 | 5 | void (async () => { 6 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 7 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 8 | 9 | const client = new KameleoLocalApiClient({ 10 | basePath: `http://localhost:${kameleoPort}`, 11 | }); 12 | 13 | // Search Chrome fingerprints 14 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", undefined, "chrome"); 15 | 16 | // Create a new profile with recommended settings 17 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 18 | const createProfileRequest = { 19 | fingerprintId: fingerprints[0].id, 20 | name: "CommonJS example", 21 | startPage: "https://kameleo.io", 22 | }; 23 | const profile = await client.profile.createProfile(createProfileRequest); 24 | 25 | // Start the profile 26 | await client.profile.startProfile(profile.id); 27 | 28 | // Wait for 10 seconds 29 | await setTimeout(10_000); 30 | 31 | // Stop the profile 32 | await client.profile.stopProfile(profile.id); 33 | })(); 34 | -------------------------------------------------------------------------------- /nodejs/commonjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commonjs", 3 | "description": "A CommonJS example (other examples are ESM)", 4 | "type": "commonjs", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/connect_with_playwright_to_chrome/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import playwright from "playwright"; 3 | import { setTimeout } from "timers/promises"; 4 | 5 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 6 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 7 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 8 | 9 | // Initialize the Kameleo client 10 | const client = new KameleoLocalApiClient({ 11 | basePath: kameleoCliUri, 12 | }); 13 | 14 | // Search Chrome fingerprints 15 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", undefined, "chrome"); 16 | 17 | // Create a new profile with recommended settings 18 | // for browser fingerprint protection 19 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 20 | const createProfileRequest = { 21 | fingerprintId: fingerprints[0].id, 22 | name: "connect with Playwright to Chrome example", 23 | }; 24 | 25 | const profile = await client.profile.createProfile(createProfileRequest); 26 | 27 | // Start the Kameleo profile and connect with Playwright through CDP 28 | const browserWSEndpoint = `ws://localhost:${kameleoPort}/playwright/${profile.id}`; 29 | const browser = await playwright.chromium.connectOverCDP(browserWSEndpoint); 30 | 31 | // It is recommended to work on the default context. 32 | // NOTE: We DO NOT recommend using multiple browser contexts, as this might interfere 33 | // with Kameleo's browser fingerprint modification features. 34 | const context = browser.contexts()[0]; 35 | const page = await context.newPage(); 36 | 37 | // Use any Playwright command to drive the browser 38 | // and enjoy full protection from bot detection products 39 | await page.goto("https://wikipedia.org"); 40 | await page.click("[name=search]"); 41 | await page.keyboard.type("Chameleon"); 42 | await page.keyboard.press("Enter"); 43 | 44 | // Wait for 5 seconds 45 | await setTimeout(5_000); 46 | 47 | // Stop the browser by stopping the Kameleo profile 48 | await client.profile.stopProfile(profile.id); 49 | -------------------------------------------------------------------------------- /nodejs/connect_with_playwright_to_chrome/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "connect_with_playwright_to_chrome", 3 | "description": "This script uses Kameleo with Playwright to automate a browser, create a profile to evade bot detection, and perform a Google search.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/connect_with_playwright_to_firefox/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import playwright from "playwright"; 3 | import { setTimeout } from "timers/promises"; 4 | 5 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 6 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 7 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 8 | 9 | // Initialize the Kameleo client 10 | const client = new KameleoLocalApiClient({ 11 | basePath: kameleoCliUri, 12 | }); 13 | 14 | // Search Firefox fingerprints 15 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", undefined, "firefox"); 16 | 17 | // Create a new profile with recommended settings 18 | // for browser fingerprint protection 19 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 20 | const createProfileRequest = { 21 | fingerprintId: fingerprints[0].id, 22 | name: "connect with Playwright to Firefox example", 23 | }; 24 | 25 | const profile = await client.profile.createProfile(createProfileRequest); 26 | 27 | // Start the Kameleo profile and connect with Playwright 28 | const browserWSEndpoint = `ws://localhost:${kameleoPort}/playwright/${profile.id}`; 29 | 30 | // The Playwright framework is not designed to connect to already running 31 | // browsers. To overcome this limitation, a tool bundled with Kameleo, named 32 | // pw-bridge will bridge the communication gap between the running Firefox 33 | // instance and this playwright script. 34 | // The exact path to the bridge executable is subject to change 35 | let pwBridgePath = process.env["PW_BRIDGE_PATH"]; 36 | if (!pwBridgePath && process.platform === "win32") { 37 | pwBridgePath = `${process.env["LOCALAPPDATA"]}\\Programs\\Kameleo\\pw-bridge.exe`; 38 | } else if (!pwBridgePath && process.platform === "darwin") { 39 | pwBridgePath = "/Applications/Kameleo.app/Contents/Resources/CLI/pw-bridge"; 40 | } 41 | 42 | const browser = await playwright.firefox.launchPersistentContext("", { 43 | executablePath: pwBridgePath, 44 | args: [`-target ${browserWSEndpoint}`], 45 | viewport: null, 46 | }); 47 | 48 | // Kameleo will open the a new page in the default browser context. 49 | // NOTE: We DO NOT recommend using multiple browser contexts, as this might interfere 50 | // with Kameleo's browser fingerprint modification features. 51 | const page = await browser.newPage(); 52 | 53 | // Use any Playwright command to drive the browser 54 | // and enjoy full protection from bot detection products 55 | await page.goto("https://wikipedia.org"); 56 | await page.click("[name=search]"); 57 | await page.keyboard.type("Chameleon"); 58 | await page.keyboard.press("Enter"); 59 | 60 | // Wait for 5 seconds 61 | await setTimeout(5_000); 62 | 63 | // Stop the browser by stopping the Kameleo profile 64 | await client.profile.stopProfile(profile.id); 65 | -------------------------------------------------------------------------------- /nodejs/connect_with_playwright_to_firefox/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "connect_with_playwright_to_firefox", 3 | "description": "This script uses Kameleo with Playwright to automate a Firefox browser, create a profile and execute a Google search.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/connect_with_puppeteer/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import puppeteer from "puppeteer"; 3 | import { setTimeout } from "timers/promises"; 4 | 5 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 6 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 7 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 8 | 9 | // Initialize the Kameleo client 10 | const client = new KameleoLocalApiClient({ 11 | basePath: kameleoCliUri, 12 | }); 13 | 14 | // Search Chrome fingerprints 15 | // (Puppeteer won't work with Firefox you can use any Chromium based browser) 16 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", undefined, "chrome"); 17 | 18 | // Create a new profile with recommended settings 19 | // for browser fingerprint protection 20 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 21 | const createProfileRequest = { 22 | fingerprintId: fingerprints[0].id, 23 | name: "connect with Puppeteer example", 24 | }; 25 | 26 | const profile = await client.profile.createProfile(createProfileRequest); 27 | 28 | // Start the Kameleo profile and connect through CDP 29 | const browserWSEndpoint = `ws://localhost:${kameleoPort}/puppeteer/${profile.id}`; 30 | const browser = await puppeteer.connect({ 31 | browserWSEndpoint, 32 | defaultViewport: null, 33 | }); 34 | const page = await browser.newPage(); 35 | 36 | // Use any Puppeteer command to drive the browser 37 | // and enjoy full protection from bot detection products 38 | await page.goto("https://wikipedia.org"); 39 | await page.click("[name=search]"); 40 | await page.keyboard.type("Chameleon"); 41 | await page.keyboard.press("Enter"); 42 | 43 | // Wait for 5 seconds 44 | await setTimeout(5_000); 45 | 46 | // Stop the browser by stopping the Kameleo profile 47 | await client.profile.stopProfile(profile.id); 48 | -------------------------------------------------------------------------------- /nodejs/connect_with_puppeteer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "connect_with_puppeteer", 3 | "description": "This script uses Kameleo with Puppeteer to automate a Chrome browser, set up a profile to avoid bot detection, and carry out a Google search.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/connect_with_selenium/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import { Builder, By, Key, until } from "selenium-webdriver"; 3 | 4 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 5 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 6 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 7 | 8 | // Initialize the Kameleo client 9 | const client = new KameleoLocalApiClient({ 10 | basePath: kameleoCliUri, 11 | }); 12 | 13 | // Search one of the fingerprints 14 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", undefined, "chrome"); 15 | 16 | // Create a new profile with recommended settings 17 | // Choose one of the fingerprints 18 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 19 | const createProfileRequest = { 20 | fingerprintId: fingerprints[0].id, 21 | name: "connect with Selenium example", 22 | }; 23 | 24 | const profile = await client.profile.createProfile(createProfileRequest); 25 | 26 | // Start the Kameleo profile and connect using WebDriver protocol 27 | const builder = new Builder().usingServer(`${kameleoCliUri}/webdriver`).withCapabilities({ 28 | "kameleo:profileId": profile.id, 29 | browserName: "Kameleo", 30 | }); 31 | const webdriver = await builder.build(); 32 | 33 | // Use any WebDriver command to drive the browser 34 | // and enjoy full protection from bot detection products 35 | await webdriver.get("https://wikipedia.org"); 36 | await webdriver.findElement(By.name("search")).sendKeys("Chameleon", Key.ENTER); 37 | await webdriver.wait(until.elementLocated(By.id("content"))); 38 | const title = await webdriver.getTitle(); 39 | console.log(`The title is ${title}`); 40 | 41 | // Wait for 5 seconds 42 | await webdriver.sleep(5000); 43 | 44 | // Stop the browser by stopping the Kameleo profile 45 | await client.profile.stopProfile(profile.id); 46 | -------------------------------------------------------------------------------- /nodejs/connect_with_selenium/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "connect_with_selenium", 3 | "description": "This script initializes a Kameleo client, creates and starts a new browser profile with recommended settings, uses Selenium WebDriver to connect to the profile and perform a Google search.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/cookie_robot/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import randomInteger from "random-int"; 3 | import { Builder } from "selenium-webdriver"; 4 | 5 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 6 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 7 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 8 | 9 | // Initialize the Kameleo client 10 | const client = new KameleoLocalApiClient({ 11 | basePath: kameleoCliUri, 12 | }); 13 | 14 | // Search one of the fingerprints 15 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", undefined, "firefox"); 16 | 17 | // Create a new profile with recommended settings 18 | // Choose one of the fingerprints 19 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 20 | const createProfileRequest = { 21 | fingerprintId: fingerprints[0].id, 22 | name: "cookie robot example", 23 | }; 24 | const profile = await client.profile.createProfile(createProfileRequest); 25 | 26 | // Start the Kameleo profile and connect to the profile using WebDriver protocol 27 | const builder = new Builder().usingServer(`http://localhost:${kameleoPort}/webdriver`).withCapabilities({ 28 | "kameleo:profileId": profile.id, 29 | browserName: "Kameleo", 30 | }); 31 | const webdriver = await builder.build(); 32 | 33 | const allSites = [ 34 | "instagram.com", 35 | "linkedin.com", 36 | "ebay.com", 37 | "pinterest.com", 38 | "reddit.com", 39 | "cnn.com", 40 | "bbc.co.uk", 41 | "nytimes.com", 42 | "reuters.com", 43 | "theguardian.com", 44 | "foxnews.com", 45 | ]; 46 | 47 | // Select sites to collect cookies from 48 | /** @type {string[]} */ 49 | const sitesToVisit = []; 50 | while (sitesToVisit.length < 5) { 51 | const site = allSites[randomInteger(allSites.length - 1)]; 52 | if (!sitesToVisit.includes(site)) { 53 | sitesToVisit.push(site); 54 | } 55 | } 56 | 57 | // Warm up profile by visiting the randomly selected sites 58 | for (const site of sitesToVisit) { 59 | await webdriver.get(`https://${site}`); 60 | await webdriver.sleep(randomInteger(5000, 15000)); 61 | } 62 | 63 | // Stop the profile 64 | await client.profile.stopProfile(profile.id); 65 | -------------------------------------------------------------------------------- /nodejs/cookie_robot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cookie_robot", 3 | "description": "This example illustrates how to use Kameleo with Selenium WebDriver to automate a browser.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import eslint from "@eslint/js"; 2 | import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"; 3 | import tseslint from "typescript-eslint"; 4 | 5 | export default tseslint.config({ 6 | files: ["**/*.{js,mjs}"], 7 | extends: [ 8 | eslint.configs.recommended, 9 | tseslint.configs.strictTypeChecked, 10 | tseslint.configs.stylisticTypeChecked, 11 | eslintPluginPrettierRecommended, 12 | ], 13 | languageOptions: { parserOptions: { projectService: true } }, 14 | rules: { 15 | "prettier/prettier": "warn", 16 | 17 | "@typescript-eslint/restrict-template-expressions": ["error", { allowNumber: true }], 18 | 19 | // "This rule requires the `strictNullChecks` compiler option to be turned on to function correctly" 20 | "@typescript-eslint/prefer-nullish-coalescing": "off", 21 | "@typescript-eslint/no-unnecessary-condition": "off", 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /nodejs/manage_cookies/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import { Builder } from "selenium-webdriver"; 3 | 4 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 5 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 6 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 7 | 8 | // Initialize the Kameleo client 9 | const client = new KameleoLocalApiClient({ 10 | basePath: kameleoCliUri, 11 | }); 12 | 13 | // Search one of the fingerprints 14 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", undefined, "firefox"); 15 | 16 | // Create a new profile with recommended settings 17 | // Choose one of the fingerprints 18 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 19 | const createProfileRequest = { 20 | fingerprintId: fingerprints[0].id, 21 | name: "manage cookies example", 22 | }; 23 | const profile = await client.profile.createProfile(createProfileRequest); 24 | 25 | // Start the Kameleo profile and connect to the profile using WebDriver protocol 26 | const builder = new Builder().usingServer(`http://localhost:${kameleoPort}/webdriver`).withCapabilities({ 27 | "kameleo:profileId": profile.id, 28 | browserName: "Kameleo", 29 | }); 30 | const webdriver = await builder.build(); 31 | 32 | // Navigate to a site which give you cookies 33 | await webdriver.get("https://www.nytimes.com"); 34 | await webdriver.sleep(5000); 35 | 36 | await webdriver.get("https://whoer.net"); 37 | await webdriver.sleep(5000); 38 | 39 | await webdriver.get("https://www.youtube.com"); 40 | await webdriver.sleep(5000); 41 | 42 | // Stop the profile 43 | await client.profile.stopProfile(profile.id); 44 | 45 | // You can list all of your cookies 46 | const cookieList = await client.cookie.listCookies(profile.id); 47 | console.log("The cookies of the profile: ", cookieList); 48 | 49 | // You can modify cookie or you can add new 50 | const newCookie = cookieList[0]; 51 | newCookie.value = "123"; 52 | const cookiesArray = new Array(newCookie); 53 | await client.cookie.addCookies(profile.id, cookiesArray); 54 | 55 | // You can delete all cookies of the profile 56 | await client.cookie.deleteCookies(profile.id); 57 | -------------------------------------------------------------------------------- /nodejs/manage_cookies/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "manage_cookies", 3 | "description": "This example illustrates how to use Kameleo with Selenium WebDriver to automate a browser.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kameleo-nodejs-examples", 3 | "description": "Various examples of using the Kameleo API", 4 | "type": "module", 5 | "engines": { 6 | "node": "^18 || ^20 || >=22" 7 | }, 8 | "scripts": { 9 | "type-check": "tsc", 10 | "lint": "eslint", 11 | "lint:fix": "eslint --fix", 12 | "lint:strict": "eslint --max-warnings=0" 13 | }, 14 | "author": "Kameleo Team", 15 | "license": "ISC", 16 | "dependencies": { 17 | "@kameleo/local-api-client": "^4.0.0", 18 | "playwright": "^1.48.0", 19 | "puppeteer": "^24.1.1", 20 | "random-int": "^3.0.0", 21 | "randomstring": "^1.3.0", 22 | "selenium-webdriver": "^4.31.0" 23 | }, 24 | "devDependencies": { 25 | "@eslint/js": "9.19.0", 26 | "@types/node": "^18", 27 | "@types/randomstring": "^1.3.0", 28 | "@types/selenium-webdriver": "^4.1.28", 29 | "eslint": "9.19.0", 30 | "eslint-config-prettier": "9.1.0", 31 | "eslint-plugin-prettier": "5.2.3", 32 | "typescript": "5.4.5", 33 | "typescript-eslint": "8.22.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /nodejs/profile_export_import/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import path from "path"; 3 | import { cwd } from "process"; 4 | import { setTimeout } from "timers/promises"; 5 | 6 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 7 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 8 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 9 | 10 | // Initialize the Kameleo client 11 | const client = new KameleoLocalApiClient({ 12 | basePath: kameleoCliUri, 13 | }); 14 | 15 | // Search one of the fingerprints 16 | const fingerprints = await client.fingerprint.searchFingerprints("desktop"); 17 | 18 | // Create a new profile with recommended settings 19 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 20 | const createProfileRequest = { 21 | fingerprintId: fingerprints[0].id, 22 | name: "profile export import example", 23 | }; 24 | let profile = await client.profile.createProfile(createProfileRequest); 25 | 26 | // export the profile to a given path 27 | const exportPath = path.join(cwd(), "test.kameleo"); 28 | 29 | await client.profile.exportProfile(profile.id, { 30 | path: exportPath, 31 | }); 32 | console.log("Profile has been exported to", cwd()); 33 | 34 | // You have to delete this profile if you want to import back 35 | await client.profile.deleteProfile(profile.id); 36 | 37 | // import the profile from the given url 38 | profile = await client.profile.importProfile({ 39 | path: exportPath, 40 | }); 41 | 42 | // Start the profile 43 | await client.profile.startProfile(profile.id); 44 | 45 | // Wait for 10 seconds 46 | await setTimeout(10_000); 47 | 48 | // Stop the profile 49 | await client.profile.stopProfile(profile.id); 50 | -------------------------------------------------------------------------------- /nodejs/profile_export_import/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "profile_export_import", 3 | "description": "This example demonstrates how to export and import a Kameleo profile using Kameleo's Local API client.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/start_browser_with_additional_options/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import { setTimeout } from "timers/promises"; 3 | 4 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 5 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 6 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 7 | 8 | // Initialize the Kameleo client 9 | const client = new KameleoLocalApiClient({ 10 | basePath: kameleoCliUri, 11 | }); 12 | 13 | // Search Chrome fingerprints 14 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", undefined, "chrome"); 15 | 16 | // Create a new profile with recommended settings 17 | // Choose one of the Chrome fingerprints 18 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 19 | const createProfileRequest = { 20 | fingerprintId: fingerprints[0].id, 21 | name: "start browser with additional options example", 22 | }; 23 | const profile = await client.profile.createProfile(createProfileRequest); 24 | 25 | // Provide additional settings for the webdriver when starting the browser 26 | // Use this command to customize the browser process by adding command-line arguments 27 | // like '--mute-audio' or '--start-maximized' 28 | // or modify the native profile settings when starting the browser 29 | 30 | // start the browser with the --mute-audio command line argument 31 | await client.profile.startProfile(profile.id, { 32 | arguments: ["mute-audio"], 33 | }); 34 | // Wait for 10 seconds 35 | await setTimeout(10_000); 36 | // Stop the profile 37 | await client.profile.stopProfile(profile.id); 38 | 39 | // start the browser with an additional Selenum option 40 | await client.profile.startProfile(profile.id, { 41 | additionalOptions: [ 42 | { 43 | key: "pageLoadStrategy", 44 | value: "eager", 45 | }, 46 | ], 47 | }); 48 | await setTimeout(10_000); 49 | await client.profile.stopProfile(profile.id); 50 | 51 | // start the browser and also set a Chrome preference 52 | await client.profile.startProfile(profile.id, { 53 | preferences: [ 54 | { 55 | key: "profile.managed_default_content_settings.images", 56 | value: 2, 57 | }, 58 | ], 59 | }); 60 | await setTimeout(10_000); 61 | await client.profile.stopProfile(profile.id); 62 | -------------------------------------------------------------------------------- /nodejs/start_browser_with_additional_options/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "start_browser_with_additional_options", 3 | "description": "This script demonstrates how to use Kameleo's Local API client to create a Chrome profile with custom WebDriver settings, such as muting audio and blocking images.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/start_with_proxy/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import { setTimeout } from "timers/promises"; 3 | 4 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 5 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 6 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 7 | 8 | // Initialize the Kameleo client 9 | const client = new KameleoLocalApiClient({ 10 | basePath: kameleoCliUri, 11 | }); 12 | 13 | // Search Chrome fingerprints 14 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", undefined, "chrome"); 15 | 16 | // Create a new profile with recommended settings 17 | // Choose one of the Chrome fingerprints 18 | // You can set your proxy up in the setProxy method 19 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 20 | const createProfileRequest = { 21 | fingerprintId: fingerprints[0].id, 22 | name: "start with proxy example", 23 | proxy: { 24 | value: "socks5", 25 | extra: { 26 | host: process.env["PROXY_HOST"] || "", 27 | port: Number(process.env["PROXY_PORT"]) || 1080, 28 | id: process.env["PROXY_USERNAME"] || "", 29 | secret: process.env["PROXY_PASSWORD"] || "", 30 | }, 31 | }, 32 | }; 33 | const profile = await client.profile.createProfile(createProfileRequest); 34 | 35 | // Start the profile 36 | await client.profile.startProfile(profile.id); 37 | 38 | // Wait for 10 seconds 39 | await setTimeout(10_000); 40 | 41 | // Stop the profile 42 | await client.profile.stopProfile(profile.id); 43 | -------------------------------------------------------------------------------- /nodejs/start_with_proxy/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "start_with_proxy", 3 | "description": "This script demonstrates how to create a Kameleo profile with a SOCKS5 proxy setup using the Kameleo Local API client.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/take_screenshot_with_puppeteer/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import puppeteer from "puppeteer"; 3 | import randomstring from "randomstring"; 4 | 5 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 6 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 7 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 8 | 9 | // Initialize the Kameleo client 10 | const client = new KameleoLocalApiClient({ 11 | basePath: kameleoCliUri, 12 | }); 13 | 14 | // Search Chrome fingerprints 15 | // (Puppeteer won't work with Firefox you can use any Chromium based browser) 16 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", undefined, "chrome"); 17 | 18 | // Create a new profile with recommended settings 19 | // for browser fingerprint protection 20 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 21 | const createProfileRequest = { 22 | fingerprintId: fingerprints[0].id, 23 | name: "take screenshot example", 24 | }; 25 | 26 | const profile = await client.profile.createProfile(createProfileRequest); 27 | 28 | // Start the Kameleo profile and connect through CDP 29 | const browserWSEndpoint = `ws://localhost:${kameleoPort}/puppeteer/${profile.id}`; 30 | const browser = await puppeteer.connect({ 31 | browserWSEndpoint, 32 | defaultViewport: null, 33 | }); 34 | const page = await browser.newPage(); 35 | 36 | // Use any Puppeteer command to drive the browser 37 | // and enjoy full protection from bot detection products 38 | await page.goto("https://en.wikipedia.org/wiki/Special:Random"); 39 | 40 | const path = `${randomstring.generate({ 41 | length: 12, 42 | charset: "alphabetic", 43 | })}.png`; 44 | 45 | // Take screenshot 46 | await page.screenshot({ 47 | path, 48 | }); 49 | 50 | // Stop the browser by stopping the Kameleo profile 51 | await client.profile.stopProfile(profile.id); 52 | -------------------------------------------------------------------------------- /nodejs/take_screenshot_with_puppeteer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "take_screenshot_with_puppeteer", 3 | "description": "This script uses Kameleo with Puppeteer to automate a Chrome browser, set up a profile to avoid bot detection, and carry out a Google search.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nodejs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["**/*.mjs", "**/*.js"], 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "checkJs": true, 6 | "module": "esnext", 7 | "target": "es2022", 8 | "moduleResolution": "node", 9 | "skipLibCheck": true, 10 | "noEmit": true, 11 | // strict includes multiple rules, see: https://www.typescriptlang.org/tsconfig/#strict 12 | "strict": true, 13 | "strictNullChecks": false, 14 | // other rules 15 | "forceConsistentCasingInFileNames": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "noImplicitReturns": true, 18 | "noPropertyAccessFromIndexSignature": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /nodejs/upgrade_profile/index.js: -------------------------------------------------------------------------------- 1 | import { KameleoLocalApiClient } from "@kameleo/local-api-client"; 2 | import { setTimeout } from "timers/promises"; 3 | 4 | // This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 5 | const kameleoPort = process.env["KAMELEO_PORT"] || 5050; 6 | const kameleoCliUri = `http://localhost:${kameleoPort}`; 7 | 8 | // Initialize the Kameleo client 9 | const client = new KameleoLocalApiClient({ 10 | basePath: kameleoCliUri, 11 | }); 12 | 13 | // Search for a Desktop fingerprint with Windows OS and Chrome browser 14 | const fingerprints = await client.fingerprint.searchFingerprints("desktop", "windows", "chrome"); 15 | 16 | // Find a fingerprint with the oldest available version of chrome 17 | const fingerprint = fingerprints.sort((a, b) => (a.browser.major > b.browser.major ? 1 : -1))[0]; 18 | 19 | // Create a new profile with recommended settings 20 | // Choose one of the fingerprints 21 | /** @type {import('@kameleo/local-api-client').CreateProfileRequest} */ 22 | const createProfileRequest = { 23 | fingerprintId: fingerprint.id, 24 | name: "upgrade profiles example", 25 | }; 26 | let profile = await client.profile.createProfile(createProfileRequest); 27 | 28 | console.log(`Profile's browser before update is: ${profile.fingerprint.browser.product} ${profile.fingerprint.browser.version}`); 29 | 30 | // The fingerprint’s browser version will be updated if there is any available on our servers 31 | profile = await client.profile.upgradeProfileKernel(profile.id); 32 | console.log(`Profile's browser after update is: ${profile.fingerprint.browser.product} ${profile.fingerprint.browser.version}`); 33 | 34 | // Start the profile 35 | await client.profile.startProfile(profile.id); 36 | 37 | // Wait for 5 seconds 38 | await setTimeout(5_000); 39 | 40 | // Stop the profile 41 | await client.profile.stopProfile(profile.id); 42 | -------------------------------------------------------------------------------- /nodejs/upgrade_profile/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "upgrade_profile", 3 | "description": "This script creates a Kameleo profile with the oldest available Chrome version on Windows, upgrades the browser version if possible, then starts and stops the profile.", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /python/.gitignore: -------------------------------------------------------------------------------- 1 | venv/ 2 | .idea/ 3 | *.kameleo 4 | *screenshot*/*.png -------------------------------------------------------------------------------- /python/automate_mobile_profiles_on_desktop/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest 3 | from selenium import webdriver 4 | from selenium.webdriver.common.by import By 5 | from selenium.webdriver.common.keys import Keys 6 | from selenium.webdriver.support import expected_conditions as EC 7 | from selenium.webdriver.support.ui import WebDriverWait 8 | import time 9 | import os 10 | 11 | 12 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 13 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 14 | 15 | client = KameleoLocalApiClient( 16 | endpoint=f'http://localhost:{kameleo_port}' 17 | ) 18 | 19 | # Search for a mobile fingerprints 20 | fingerprints = client.fingerprint.search_fingerprints( 21 | device_type='mobile', 22 | os_family='ios', 23 | browser_product='safari' 24 | ) 25 | 26 | # Create a new profile with automatic recommended settings 27 | # Choose one of the fingerprints 28 | # Kameleo launches mobile profiles with our Chroma browser 29 | create_profile_request = CreateProfileRequest( 30 | fingerprint_id=fingerprints[0].id, 31 | name='automate mobile profiles on desktop example') 32 | profile = client.profile.create_profile(create_profile_request) 33 | 34 | # Start the profile 35 | client.profile.start_profile(profile.id, { 36 | # This allows you to click on elements using the cursor when emulating a touch screen in the browser. 37 | # If you leave this out, your script may time out after clicks and fail. 38 | 'additionalOptions': [ 39 | { 40 | 'key': 'disableTouchEmulation', 41 | 'value': True, 42 | }, 43 | ], 44 | }) 45 | 46 | # In this example we show how you can automate the mobile profile with Selenium 47 | # You can also do this with Puppeteer or Playwright 48 | options = webdriver.ChromeOptions() 49 | options.add_experimental_option('kameleo:profileId', profile.id) 50 | driver = webdriver.Remote( 51 | command_executor=f'http://localhost:{kameleo_port}/webdriver', 52 | options=options 53 | ) 54 | 55 | # Use any WebDriver command to drive the browser 56 | # and enjoy full protection from bot detection products 57 | driver.get('https://wikipedia.org') 58 | driver.find_element(By.NAME, 'search').send_keys('Chameleon', Keys.ENTER) 59 | WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'content'))) 60 | print(f'The title is {driver.title}') 61 | 62 | # Wait for 5 seconds 63 | time.sleep(5) 64 | 65 | # Stop the browser by stopping the Kameleo profile 66 | client.profile.stop_profile(profile.id) 67 | -------------------------------------------------------------------------------- /python/basic_profile_operations/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest, UpdateProfileRequest, WebglMetaChoice, WebglMetaSpoofingOptions 3 | import time 4 | import os 5 | 6 | 7 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 8 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 9 | 10 | client = KameleoLocalApiClient( 11 | endpoint=f'http://localhost:{kameleo_port}' 12 | ) 13 | 14 | # Search Chrome fingerprints 15 | # Possible deviceType value: desktop, mobile 16 | # Possible browserProduct value: chrome, firefox, edge, ... 17 | # Possible osFamily values: windows, macos, linux, android, ios 18 | # Examples of browserVersion values that limit the major version of the fingeprint: 135, >134, ... 19 | # You can use empty parameters as well, Kameleo provides recent and varied fingerprints by default 20 | fingerprints = client.fingerprint.search_fingerprints( 21 | device_type='desktop', 22 | browser_product='chrome', 23 | browser_version='>134', 24 | ) 25 | 26 | # Create a new profile with recommended settings for browser fingerprinting protection 27 | # Choose one of the Chrome fingerprints 28 | # You can setup here all of the profile options like WebGL 29 | create_profile_request = CreateProfileRequest( 30 | fingerprint_id=fingerprints[0].id, 31 | language="es-es", 32 | name='create profile example', 33 | webgl='noise', 34 | webgl_meta=WebglMetaChoice( 35 | value='manual', 36 | extra=WebglMetaSpoofingOptions( 37 | vendor='Google Inc.', 38 | renderer='ANGLE (Intel(R) HD Graphics 630 Direct3D11 vs_5_0 ps_5_0)')), 39 | start_page='https://kameleo.io', 40 | password_manager='enabled') 41 | profile = client.profile.create_profile(create_profile_request) 42 | 43 | # Start the browser profile 44 | client.profile.start_profile(profile.id) 45 | 46 | # Wait for 10 seconds 47 | time.sleep(10) 48 | 49 | # Stop the browser by stopping the Kameleo profile 50 | client.profile.stop_profile(profile.id) 51 | 52 | # Duplicate the previously created profile 53 | duplicated_profile = client.profile.duplicate_profile(profile.id) 54 | print(f'Profile {duplicated_profile.name} is created') 55 | 56 | # Change every property that you want to update 57 | update_profile_request = UpdateProfileRequest( 58 | name = 'duplicate profile example', 59 | webgl_meta = WebglMetaChoice(value='automatic') 60 | ) 61 | 62 | # Send the update request and the response will be your updated profile 63 | duplicated_profile = client.profile.update_profile(duplicated_profile.id, update_profile_request) 64 | 65 | # Start the duplicated browser profile 66 | client.profile.start_profile(duplicated_profile.id) 67 | 68 | # Wait for 10 seconds 69 | time.sleep(10) 70 | 71 | # Stop the browser by stopping the Kameleo profile 72 | client.profile.stop_profile(duplicated_profile.id) 73 | 74 | # Delete original profile 75 | # Profiles need to be deleted explicitly becase they are persisted so they are available after restarting Kameleo 76 | client.profile.delete_profile(profile.id) 77 | -------------------------------------------------------------------------------- /python/clean_workspace/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | import os 3 | 4 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 5 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 6 | 7 | client = KameleoLocalApiClient( 8 | endpoint=f'http://localhost:{kameleo_port}' 9 | ) 10 | 11 | profiles = client.profile.list_profiles() 12 | for profile in profiles: 13 | client.profile.delete_profile(profile.id) 14 | 15 | print(f'{len(profiles)} profiles deleted.') 16 | -------------------------------------------------------------------------------- /python/connect_with_playwright_to_chrome/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest 3 | from playwright.sync_api import sync_playwright 4 | import time 5 | import os 6 | 7 | 8 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 9 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 10 | 11 | client = KameleoLocalApiClient( 12 | endpoint=f'http://localhost:{kameleo_port}' 13 | ) 14 | 15 | # Search Chrome fingerprints 16 | fingerprints = client.fingerprint.search_fingerprints( 17 | device_type='desktop', 18 | browser_product='chrome' 19 | ) 20 | 21 | # Create a new profile with recommended settings 22 | # Choose one of the fingerprints 23 | create_profile_request = CreateProfileRequest( 24 | fingerprint_id=fingerprints[0].id, 25 | name='connect with Playwright to Chrome example') 26 | profile = client.profile.create_profile(create_profile_request) 27 | 28 | # Start the Kameleo profile and connect with Playwright through CDP 29 | browser_ws_endpoint = f'ws://localhost:{kameleo_port}/playwright/{profile.id}' 30 | with sync_playwright() as playwright: 31 | browser = playwright.chromium.connect_over_cdp(endpoint_url=browser_ws_endpoint) 32 | context = browser.contexts[0] 33 | page = context.new_page() 34 | 35 | # Use any Playwright command to drive the browser 36 | # and enjoy full protection from bot detection products 37 | page.goto('https://wikipedia.org') 38 | page.click('[name=search]') 39 | page.keyboard.type('Chameleon') 40 | page.keyboard.press('Enter') 41 | 42 | # Wait for 5 seconds 43 | time.sleep(5) 44 | 45 | # Stop the browser by stopping the Kameleo profile 46 | client.profile.stop_profile(profile.id) 47 | -------------------------------------------------------------------------------- /python/connect_with_playwright_to_firefox/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest 3 | from playwright.sync_api import sync_playwright 4 | import time 5 | from os import path, getenv 6 | from platform import system 7 | import os 8 | 9 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 10 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 11 | 12 | client = KameleoLocalApiClient( 13 | endpoint=f'http://localhost:{kameleo_port}' 14 | ) 15 | 16 | # Search Firefox fingerprints 17 | fingerprints = client.fingerprint.search_fingerprints( 18 | device_type='desktop', 19 | browser_product='firefox' 20 | ) 21 | 22 | # Create a new profile with recommended settings 23 | # Choose one of the fingerprints 24 | create_profile_request = CreateProfileRequest( 25 | fingerprint_id=fingerprints[0].id, 26 | name='connect with Playwright to Firefox example') 27 | profile = client.profile.create_profile(create_profile_request) 28 | 29 | # Start the Kameleo profile and connect with Playwright 30 | browser_ws_endpoint = f'ws://localhost:{kameleo_port}/playwright/{profile.id}' 31 | with sync_playwright() as playwright: 32 | # The Playwright framework is not designed to connect to already running 33 | # browsers. To overcome this limitation, a tool bundled with Kameleo, named 34 | # pw-bridge will bridge the communication gap between the running Firefox 35 | # instance and this playwright script. 36 | # The exact path to the bridge executable is subject to change 37 | pw_bridge_path = getenv('PW_BRIDGE_PATH') 38 | if pw_bridge_path == None and system() == 'Windows': 39 | pw_bridge_path = path.expandvars(r'%LOCALAPPDATA%\Programs\Kameleo\pw-bridge.exe') 40 | elif pw_bridge_path == None and system() == 'Darwin': 41 | pw_bridge_path = '/Applications/Kameleo.app/Contents/Resources/CLI/pw-bridge' 42 | browser = playwright.firefox.launch_persistent_context( 43 | '', 44 | executable_path=pw_bridge_path, 45 | args=[f'-target {browser_ws_endpoint}'], 46 | viewport=None) 47 | 48 | # Kameleo will open the a new page in the default browser context. 49 | # NOTE: We DO NOT recommend using multiple browser contexts, as this might interfere 50 | # with Kameleo's browser fingerprint modification features. 51 | page = browser.new_page() 52 | 53 | # Use any Playwright command to drive the browser 54 | # and enjoy full protection from bot detection products 55 | page.goto('https://wikipedia.org') 56 | page.click('[name=search]') 57 | page.keyboard.type('Chameleon') 58 | page.keyboard.press('Enter') 59 | 60 | # Wait for 5 seconds 61 | time.sleep(5) 62 | 63 | # Stop the browser by stopping the Kameleo profile 64 | client.profile.stop_profile(profile.id) 65 | -------------------------------------------------------------------------------- /python/connect_with_puppeteer/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest 3 | import pyppeteer 4 | import time 5 | import asyncio 6 | import os 7 | 8 | 9 | async def main(): 10 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 11 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 12 | 13 | client = KameleoLocalApiClient( 14 | endpoint=f'http://localhost:{kameleo_port}' 15 | ) 16 | 17 | # Search Chrome fingerprints 18 | fingerprints = client.fingerprint.search_fingerprints( 19 | device_type='desktop', 20 | browser_product='chrome' 21 | ) 22 | 23 | # Create a new profile with recommended settings 24 | # Choose one of the fingerprints 25 | create_profile_request = CreateProfileRequest( 26 | fingerprint_id=fingerprints[0].id, 27 | name='connect with Puppeteer example') 28 | profile = client.profile.create_profile(create_profile_request) 29 | 30 | # Start the Kameleo profile and connect through CDP 31 | browser_ws_endpoint = f'ws://localhost:{kameleo_port}/puppeteer/{profile.id}' 32 | browser = await pyppeteer.launcher.connect(browserWSEndpoint=browser_ws_endpoint, defaultViewport=False) 33 | page = await browser.newPage() 34 | 35 | # Use any Puppeteer command to drive the browser 36 | # and enjoy full protection from bot detection products 37 | await page.goto('https://wikipedia.org') 38 | await page.click('[name=search') 39 | await page.keyboard.type('Chameleon') 40 | await page.keyboard.press('Enter') 41 | 42 | # Wait for 5 seconds 43 | time.sleep(5) 44 | 45 | # Stop the browser by stopping the Kameleo profile 46 | client.profile.stop_profile(profile.id) 47 | 48 | asyncio.run(main()) 49 | -------------------------------------------------------------------------------- /python/connect_with_selenium/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest 3 | from selenium import webdriver 4 | import time 5 | import os 6 | 7 | 8 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 9 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 10 | 11 | client = KameleoLocalApiClient( 12 | endpoint=f'http://localhost:{kameleo_port}' 13 | ) 14 | 15 | # Search Chrome fingerprints 16 | fingerprints = client.fingerprint.search_fingerprints( 17 | device_type='desktop', 18 | browser_product='chrome' 19 | ) 20 | 21 | # Create a new profile with recommended settings 22 | # Choose one of the fingerprints 23 | create_profile_request = CreateProfileRequest( 24 | fingerprint_id=fingerprints[0].id, 25 | name='connect to Selenium example') 26 | profile = client.profile.create_profile(create_profile_request) 27 | 28 | # Start the Kameleo profile and connect using WebDriver protocol 29 | options = webdriver.ChromeOptions() 30 | options.add_experimental_option('kameleo:profileId', profile.id) 31 | driver = webdriver.Remote( 32 | command_executor=f'http://localhost:{kameleo_port}/webdriver', 33 | options=options 34 | ) 35 | 36 | # Use any WebDriver command to drive the browser 37 | # and enjoy full protection from bot detection products 38 | driver.get('https://wikipedia.org') 39 | driver.find_element('name', 'search').send_keys('Chameleon\n') 40 | print(driver.title) 41 | 42 | # Wait for 5 seconds 43 | time.sleep(5) 44 | 45 | # Stop the browser by stopping the Kameleo profile 46 | client.profile.stop_profile(profile.id) 47 | -------------------------------------------------------------------------------- /python/cookie_robot/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest 3 | from selenium import webdriver 4 | import time 5 | import os 6 | import random 7 | 8 | 9 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 10 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 11 | 12 | client = KameleoLocalApiClient( 13 | endpoint=f'http://localhost:{kameleo_port}' 14 | ) 15 | 16 | # Search Firefox fingerprints 17 | fingerprints = client.fingerprint.search_fingerprints( 18 | device_type='desktop', 19 | browser_product='firefox' 20 | ) 21 | 22 | # Create a new profile with recommended settings for browser fingerprinting protection 23 | # Choose one of the Firefox fingerprints 24 | create_profile_request = CreateProfileRequest( 25 | fingerprint_id=fingerprints[0].id, 26 | name='cookie robot example') 27 | profile = client.profile.create_profile(create_profile_request) 28 | 29 | # Start the Kameleo profile and connect using WebDriver protocol 30 | options = webdriver.ChromeOptions() 31 | options.add_experimental_option('kameleo:profileId', profile.id) 32 | driver = webdriver.Remote( 33 | command_executor=f'http://localhost:{kameleo_port}/webdriver', 34 | options=options 35 | ) 36 | 37 | all_sites = ["instagram.com", 38 | "linkedin.com", 39 | "ebay.com", 40 | "pinterest.com", 41 | "reddit.com", 42 | "cnn.com", 43 | "bbc.co.uk", 44 | "nytimes.com", 45 | "reuters.com", 46 | "theguardian.com", 47 | "foxnews.com"] 48 | 49 | # Select sites to collect cookies from 50 | sites_to_visit = [] 51 | while len(sites_to_visit) < 5: 52 | site = all_sites[random.randint(0, len(all_sites) - 1)] 53 | if not site in set(sites_to_visit) : 54 | sites_to_visit.append(site) 55 | 56 | # Warm up profile by visiting the randomly selected sites 57 | for site in sites_to_visit: 58 | driver.get(f'https://{site}') 59 | time.sleep(random.randint(5, 15)) 60 | 61 | # Stop the browser by stopping the Kameleo profile 62 | client.profile.stop_profile(profile.id) 63 | -------------------------------------------------------------------------------- /python/manage_cookies/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest, CookieRequest 3 | from selenium import webdriver 4 | import time 5 | import os 6 | 7 | 8 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 9 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 10 | 11 | client = KameleoLocalApiClient( 12 | endpoint=f'http://localhost:{kameleo_port}' 13 | ) 14 | 15 | # Search Firefox fingerprints 16 | fingerprints = client.fingerprint.search_fingerprints( 17 | device_type='desktop', 18 | browser_product='firefox' 19 | ) 20 | 21 | # Create a new profile with recommended settings for browser fingerprinting protection 22 | # Choose one of the Firefox fingerprints 23 | create_profile_request = CreateProfileRequest( 24 | fingerprint_id=fingerprints[0].id, 25 | name='manage cookies example') 26 | profile = client.profile.create_profile(create_profile_request) 27 | 28 | # Start the Kameleo profile and connect using WebDriver protocol 29 | options = webdriver.ChromeOptions() 30 | options.add_experimental_option('kameleo:profileId', profile.id) 31 | driver = webdriver.Remote( 32 | command_executor=f'http://localhost:{kameleo_port}/webdriver', 33 | options=options 34 | ) 35 | 36 | # Navigate to a site which give you cookies 37 | driver.get('https://whoer.net') 38 | time.sleep(5) 39 | 40 | driver.get('https://youtube.com') 41 | time.sleep(5) 42 | 43 | driver.get('https://www.nytimes.com') 44 | time.sleep(5) 45 | 46 | # Stop the browser by stopping the Kameleo profile 47 | client.profile.stop_profile(profile.id) 48 | 49 | # You can list all of your cookies 50 | cookie_list = client.cookie.list_cookies(profile.id) 51 | print(f'There are {len(cookie_list)} cookies in the profile') 52 | 53 | # You can modify cookie or you can add new 54 | cookie = cookie_list[0] 55 | new_cookie = CookieRequest(domain=cookie.domain, name=cookie.name, path=cookie.path, value=cookie.value, 56 | host_only=cookie.host_only, http_only=cookie.http_only, secure=cookie.secure, 57 | same_site=cookie.same_site, expiration_date=cookie.expiration_date) 58 | cookie_array = [new_cookie] 59 | client.cookie.add_cookies(profile.id, cookie_array) 60 | 61 | # You can delete all cookies of the profile 62 | client.cookie.delete_cookies(profile.id) 63 | -------------------------------------------------------------------------------- /python/profile_export_import/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest, ExportProfileRequest, ImportProfileRequest 3 | import time 4 | import os 5 | 6 | 7 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 8 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 9 | 10 | client = KameleoLocalApiClient( 11 | endpoint=f'http://localhost:{kameleo_port}' 12 | ) 13 | 14 | # Search Chrome fingerprints 15 | fingerprints = client.fingerprint.search_fingerprints( 16 | device_type='desktop', 17 | browser_product='chrome' 18 | ) 19 | 20 | # Create a new profile with recommended settings for browser fingerprinting protection 21 | # Choose one of the Chrome fingerprints 22 | create_profile_request = CreateProfileRequest( 23 | fingerprint_id=fingerprints[0].id, 24 | name='profile export import example') 25 | profile = client.profile.create_profile(create_profile_request) 26 | 27 | # Export the profile to a given path 28 | folder = os.path.dirname(os.path.realpath(__file__)) 29 | path = os.path.join(folder, 'test.kameleo') 30 | result = client.profile.export_profile(profile.id, ExportProfileRequest(path=path)) 31 | print(f'Profile has been exported to {folder}') 32 | 33 | # You have to delete this profile if you want to import back 34 | client.profile.delete_profile(profile.id) 35 | 36 | # Import the profile from the given url 37 | profile = client.profile.import_profile(ImportProfileRequest(path=path)) 38 | 39 | # Start the profile 40 | client.profile.start_profile(profile.id) 41 | 42 | # Wait for 5 seconds 43 | time.sleep(5) 44 | 45 | # Stop the browser by stopping the Kameleo profile 46 | client.profile.stop_profile(profile.id) 47 | -------------------------------------------------------------------------------- /python/requirements.txt: -------------------------------------------------------------------------------- 1 | kameleo.local_api_client==4.0.0 2 | selenium==4.31.0 3 | playwright==1.46.0 4 | pyppeteer==2.0.0 -------------------------------------------------------------------------------- /python/start_browser_with_additional_options/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest, BrowserSettings, Preference 3 | import time 4 | import os 5 | 6 | 7 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 8 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 9 | 10 | client = KameleoLocalApiClient( 11 | endpoint=f'http://localhost:{kameleo_port}' 12 | ) 13 | 14 | # Search Chrome fingerprints 15 | fingerprints = client.fingerprint.search_fingerprints( 16 | device_type='desktop', 17 | browser_product='chrome' 18 | ) 19 | 20 | # Create a new profile with recommended settings for browser fingerprinting protection 21 | # Choose one of the Chrome fingerprints 22 | create_profile_request = CreateProfileRequest( 23 | fingerprint_id=fingerprints[0].id, 24 | name='start browser with additional options example') 25 | profile = client.profile.create_profile(create_profile_request) 26 | 27 | # Provide additional settings for the web driver when starting the browser 28 | # Use this command to customize the browser process by adding command-line arguments 29 | # like '--mute-audio' or '--start-maximized' 30 | # or modify the native profile settings when starting the browser 31 | 32 | # start the browser with the --mute-audio command line argument 33 | client.profile.start_profile(profile.id, BrowserSettings( 34 | arguments=['mute-audio'], 35 | )) 36 | # Wait for 10 seconds 37 | time.sleep(10) 38 | # Stop the profile 39 | client.profile.stop_profile(profile.id) 40 | 41 | # start the browser with an additional Selenum option 42 | client.profile.start_profile(profile.id, BrowserSettings( 43 | additional_options=[ 44 | Preference(key='pageLoadStrategy', value='eager'), 45 | ] 46 | )) 47 | time.sleep(10) 48 | client.profile.stop_profile(profile.id) 49 | 50 | # start the browser and also set a Chrome preference 51 | client.profile.start_profile(profile.id, BrowserSettings( 52 | preferences=[ 53 | Preference(key='profile.managed_default_content_settings.images', value=2), 54 | ] 55 | )) 56 | time.sleep(10) 57 | client.profile.stop_profile(profile.id) 58 | -------------------------------------------------------------------------------- /python/start_with_proxy/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest, ProxyChoice, Server 3 | import time 4 | import os 5 | 6 | 7 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 8 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 9 | 10 | PROXY_HOST = os.getenv('PROXY_HOST', '') 11 | PROXY_PORT = int(os.getenv('PROXY_PORT', '')) 12 | PROXY_USERNAME = os.getenv('PROXY_USERNAME', '') 13 | PROXY_PASSWORD = os.getenv('PROXY_PASSWORD', '') 14 | 15 | client = KameleoLocalApiClient( 16 | endpoint=f'http://localhost:{kameleo_port}' 17 | ) 18 | 19 | # Search Chrome fingerprints 20 | fingerprints = client.fingerprint.search_fingerprints( 21 | device_type='desktop', 22 | browser_product='chrome' 23 | ) 24 | 25 | # Create a new profile with recommended settings for browser fingerprinting protection 26 | # Choose one of the Chrome fingerprints 27 | create_profile_request = CreateProfileRequest( 28 | fingerprint_id=fingerprints[0].id, 29 | name='start with proxy example', 30 | proxy=ProxyChoice( 31 | value='socks5', 32 | extra=Server(host=PROXY_HOST, port=PROXY_PORT, id=PROXY_USERNAME, secret=PROXY_PASSWORD) 33 | )) 34 | profile = client.profile.create_profile(create_profile_request) 35 | 36 | # Start the browser profile 37 | client.profile.start_profile(profile.id) 38 | 39 | # Wait for 10 seconds 40 | time.sleep(10) 41 | 42 | # Stop the browser by stopping the Kameleo profile 43 | client.profile.stop_profile(profile.id) 44 | -------------------------------------------------------------------------------- /python/take_screenshot_with_puppeteer/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest 3 | import asyncio 4 | import pyppeteer 5 | import random 6 | import string 7 | import os 8 | 9 | 10 | async def main(): 11 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 12 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 13 | 14 | client = KameleoLocalApiClient( 15 | endpoint=f'http://localhost:{kameleo_port}' 16 | ) 17 | 18 | # Search Chrome fingerprints 19 | fingerprints = client.fingerprint.search_fingerprints( 20 | device_type='desktop', 21 | browser_product='chrome' 22 | ) 23 | 24 | # Create a new profile with recommended settings for browser fingerprinting protection 25 | # Choose one of the Chrome fingerprints 26 | # You can setup here all of the profile options like WebGL 27 | create_profile_request = CreateProfileRequest( 28 | fingerprint_id=fingerprints[0].id, 29 | name='take screenshot example') 30 | profile = client.profile.create_profile(create_profile_request) 31 | 32 | # Start the Kameleo profile and connect through CDP 33 | browser_ws_endpoint = f'ws://localhost:{kameleo_port}/puppeteer/{profile.id}' 34 | browser = await pyppeteer.launcher.connect(browserWSEndpoint=browser_ws_endpoint, defaultViewport=False) 35 | page = await browser.newPage() 36 | 37 | # Open a random page from wikipedia 38 | await page.goto('https://en.wikipedia.org/wiki/Special:Random') 39 | 40 | res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10)) 41 | 42 | # Take screenshot 43 | await page.screenshot({'path': f'{res}.png', 'fullPage': True}) 44 | 45 | # Stop the browser by stopping the Kameleo profile 46 | client.profile.stop_profile(profile.id) 47 | 48 | asyncio.run(main()) 49 | -------------------------------------------------------------------------------- /python/upgrade_profile/app.py: -------------------------------------------------------------------------------- 1 | from kameleo.local_api_client import KameleoLocalApiClient 2 | from kameleo.local_api_client.models import CreateProfileRequest 3 | import time 4 | import os 5 | 6 | 7 | # This is the port Kameleo.CLI is listening on. Default value is 5050, but can be overridden in appsettings.json file 8 | kameleo_port = os.getenv('KAMELEO_PORT', '5050') 9 | 10 | client = KameleoLocalApiClient( 11 | endpoint=f'http://localhost:{kameleo_port}' 12 | ) 13 | 14 | # Search for a Desktop fingerprint with Windows OS and Chrome browser 15 | fingerprints = client.fingerprint.search_fingerprints( 16 | device_type='desktop', 17 | os_family='windows', 18 | browser_product='chrome' 19 | ) 20 | 21 | # Find a fingerprint with the oldest available version of chrome 22 | fingerprint = sorted(fingerprints, key=lambda x: x.browser.major)[0] 23 | 24 | # Create a new profile with recommended settings 25 | # Choose one of the fingerprints 26 | create_profile_request = CreateProfileRequest( 27 | fingerprint_id=fingerprint.id, 28 | name='upgrade profiles example') 29 | profile = client.profile.create_profile(create_profile_request) 30 | 31 | print( 32 | f'Profile\'s browser before update is {profile.fingerprint.browser.product} {profile.fingerprint.browser.version}') 33 | 34 | # The fingerprint’s browser version will be updated if there is any available on our servers 35 | profile = client.profile.upgrade_profile_kernel(profile.id) 36 | print( 37 | f'Profile\'s browser after update is {profile.fingerprint.browser.product} {profile.fingerprint.browser.version}') 38 | 39 | # Start the browser profile 40 | client.profile.start_profile(profile.id) 41 | 42 | # Wait for 5 seconds 43 | time.sleep(5) 44 | 45 | # Stop the browser by stopping the Kameleo profile 46 | client.profile.stop_profile(profile.id) 47 | --------------------------------------------------------------------------------