簡體   English   中英

C# Selenium 在頁面加載時注入/執行 JS

[英]C# Selenium Inject/execute JS on page load

我正在使用帶有 C# 10 的 .NET Core 6。

我想要實現的是在無頭模式下運行 Selenium,同時保持“不可檢測”。 我按照這里的說明進行操作: https ://intoli.com/blog/not-possible-to-block-chrome-headless/ 它提供了一個頁面來測試您的機器人: https ://intoli.com/blog/not- 可能阻止 chrome-headless/chrome-headless-test.html

無頭模式會導致某些 JS 變量(如 window.chrome)未設置或無效,從而導致檢測到機器人。

IJavaScriptExecutor 不起作用,因為它在頁面加載后運行。 同一作者在本文中提到您必須捕獲響應並注入 JS: https ://intoli.com/blog/making-chrome-headless-undetectable/(將其放在一起部分)

由於本文使用 python,我遵循了這個: https ://www.automatetheplanet.com/webdriver-capture-modify-http-traffic/ 和這個: Titanium Web Proxy - Can't modify request body which uses the Titanium Web Proxy library (在這里找到: https ://github.com/justcoding121/titanium-web-proxy)

為了測試,我使用了這個站點http://www.example.com並嘗試修改響應(更改 HTML 中的某些內容,設置 JS 變量等)

這是代理類:

public static class Proxy
    {
        static ProxyServer proxyServer = new ProxyServer(userTrustRootCertificate: true);
        public static void StartProxy()
        {
            //Run on port 8080, decrypt ssl
            ExplicitProxyEndPoint explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8080, true);

            proxyServer.Start();
            proxyServer.AddEndPoint(explicitEndPoint);

            proxyServer.BeforeResponse += OnBeforeResponse;
        }

        static async Task OnBeforeResponse(object sender, SessionEventArgs ev)
        {
            var request = ev.HttpClient.Request;
            var response = ev.HttpClient.Response;

            //Modify title tag in example.com
            if (String.Equals(ev.HttpClient.Request.RequestUri.Host, "www.example.com", StringComparison.OrdinalIgnoreCase))
            {
                var body = await ev.GetResponseBodyAsString();

                body = body.Replace("<title>Example Domain</title>", "<title>Completely New Title</title>");

                ev.SetResponseBodyString(body);
            }
        }

        public static void StopProxy()
        {
            proxyServer.Stop();
        }
}

這是硒代碼:

Proxy.StartProxy();

string url = "localhost:8080";
var seleniumProxy = new OpenQA.Selenium.Proxy 
{
    HttpProxy = url,
    SslProxy = url,
    FtpProxy = url
};

ChromeOptions options = new ChromeOptions();
options.AddArgument("ignore-certificate-errors");
options.Proxy = seleniumProxy;

IWebDriver driver = new ChromeDriver(@"C:\ChromeDrivers\103\", options);
driver.Manage().Window.Maximize();
driver.Navigate().GoToUrl("http://www.example.com");

Console.ReadLine();
TornCityBot.Proxy.StopProxy();

當 selenium 加載http://www.example.com時, <title>Example Domain</title>應該更改為<title>Completely New Title</title> ,但沒有任何變化。 我嘗試將代理 URL 設置為 http://localhost:8080、127.0.0.1:8080、localhost:8080 等,但沒有任何變化。

作為測試,我運行了代碼並讓代理保持開啟狀態。 然后我在 git bash 中運行curl --proxy http://localhost:8080 http://www.example.com ,輸出為:

<!doctype html>
<html>
<head>
    <title>Completely New Title</title>
. . .

代理正在工作,它正在修改 curl 命令的響應。 但由於某種原因,它不適用於硒。

如果你們有一個也可以在 HTTPS 上工作的解決方案,或者在頁面加載時執行 JavaScript 的更好方法,那就太好了。 如果不可能,那么我可能需要忘記無頭。

提前感謝您的幫助。

Selenium.WebDriver 4.3.0ChromeDriver 103

嘗試使用ExecuteCdpCommand方法

var options = new ChromeOptions();
options.AddArgument("--headless");
options.AddArgument("--user-agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'");

using var driver = new ChromeDriver(options);

Dictionary<string, object> cmdParams= new();
cmdParams.Add("source", "Object.defineProperty(navigator, 'webdriver', { get: () => false });");
driver.ExecuteCdpCommand("Page.addScriptToEvaluateOnNewDocument", cmdParams);

使用這段代碼,我們繞過了前兩個,但是如果您按照您已經提到的指南進行操作,我認為繞過其余部分很容易。

在此處輸入圖像描述

更新

var initialScript = @"Object.defineProperty(Notification, 'permission', {
                        get: function () { return ''; }
                        })                                
                        window.chrome = true
                        Object.defineProperty(navigator, 'webdriver', {
                        get: () => false})  
                        Object.defineProperty(window, 'chrome', {
                        get: () => true})  
                        Object.defineProperty(navigator, 'plugins', {
                        writeable: true,
                        configurable: true,
                        enumerable: true,
                        value: 'works'})                        
                        navigator.plugins.length = 1                                
                        Object.defineProperty(navigator, 'language', {
                        get: () => 'el - GR'});
                        Object.defineProperty(navigator, 'deviceMemory', {
                        get: () => 8});
                        Object.defineProperty(navigator, 'hardwareConcurrency', {
                        get: () => 8});";

cmdParams.Add("source", initialScript);
driver.ExecuteCdpCommand("Page.addScriptToEvaluateOnNewDocument", cmdParams);

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM