I'm working on an automation for a web portal that uses Akamai anti-bot detection.
The issue is the following: when I run my code inside a Class Library (DLL), I’m able to bypass Akamai detection and successfully generate a session. However, when I use the exact same code inside a WPF application (triggered from a button click event), it fails — the session is not generated because Akamai blocks it.
I initially thought the issue was related to missing dependencies in WPF, so I installed EO.WebBrowser.WPF, which is required for WPF apps. However, that did not solve the problem — the session still isn’t generated.
So at this point, I have:
- The same code
- Different environments (Class Library vs WPF)
- Different results (works vs blocked by Akamai)
I also tried wrapping the execution in a Task , but that didn’t help.
What could be causing this difference in behavior?
Code: C#
// Configure EO.WebBrowser engine options
EngineOptions.Default.CachePath = @"C:\Temp\EOCache";
EngineOptions.Default.ExtraCommandLineArgs =
"--headless " +
"--disable-blink-features=AutomationControlled " +
"--user-agent=\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\"";
string mainPageCaptcha = string.Empty;
// Use Stopwatch to enforce a precise 60-second timeout
Stopwatch sw = Stopwatch.StartNew();
int pollingInterval = 500;
using (ThreadRunner threadRunner = new ThreadRunner())
{
WebView webView = threadRunner.CreateWebView();
// Variable to store the HTML content of the page
string htmlContent = string.Empty;
threadRunner.Send(() =>
{
try
{
// Initial page load (INFONAVIT portal)
webView.LoadUrlAndWait(sURLtoNavigate);
// Get HTML after initial load
htmlContent = webView.GetHtml();
#region INITIAL CAPTCHA
// Wait until the CAPTCHA element is available (max 60 seconds)
while (sw.ElapsedMilliseconds < 60000)
{
// Execute script to extract CAPTCHA text
object result = webView.EvalScript(@"
(() => {
const el = document.querySelector('textPath');
return el ? el.textContent.trim() : null;
})()");
if (result != null && result is string text && !string.IsNullOrEmpty(text))
{
mainPageCaptcha = text;
sw.Stop();
break;
}
Thread.Sleep(pollingInterval);
}
// Validate that CAPTCHA was retrieved
if (string.IsNullOrEmpty(mainPageCaptcha))
{
Log.Info("[OpinionINFONAVIT - ERROR]: Failed to retrieve CAPTCHA from main page");
// Stop execution due to failure
webView.Destroy();
bDescargaOpinion = false;
return;
}
#endregion
#region INITIAL LOGIN
// Fill in form fields (Employer ID, Email, Password, CAPTCHA)
// Employer Registration Number (NRP)
TypeText(webView, "#nrp", sNumRegPatr, 120);
// Email
TypeText(webView, "#correo", sCorreoPortal, 115);
// Password
TypeText(webView, "#pwd", sContraPortal, 112);
// CAPTCHA
TypeText(webView, "[name=\"captchaInput\"]", mainPageCaptcha, 184);
htmlContent = webView.GetHtml();
// Click the "Login" button
webView.EvalScript(@"
(() => {
const btns = [...document.querySelectorAll('button')];
const btn = btns.find(b => b.textContent.trim().toLowerCase().includes('iniciar'));
if (btn) btn.click();
})()");
Thread.Sleep(2500);
// Get HTML after login attempt
htmlContent = webView.GetHtml();
// Verify if redirected to the expected page (CSF page)
if (!htmlContent.Contains("constancia-de-situacion-fiscal"))
{
Log.Error("[OpinionINFONAVIT - ERROR]: Session was NOT generated - HTML:\n\n" + htmlContent + "\n");
// Clean up and stop execution
threadRunner.Send(() =>
{
webView.Destroy();
});
bDescargaOpinion = false;
return;
}
#endregion
}
catch (Exception ex)
{
Log.Error("[OpinionINFONAVIT - EXCEPTION]: " + ex.Message);
}
});
}