当前位置: 首页 > 知识库问答 >
问题:

Selenium headless:如何使用Selenium绕过Cloudflare检测

狄卓君
2023-03-14

希望专家能帮我解答硒/云闪之谜。我可以让一个网站在正常(非无头)硒加载,但无论我尝试什么,我不能让它加载在无头。

我遵循了StackOverflow帖子的建议,比如是否有无法检测到的SeleniumWebDriver版本?。我还研究了windowwindow的所有属性。导航器对象并修复了无头和无头之间的所有差异,但不知何故,仍在检测无头。在这一点上,我非常好奇Cloudflare如何能够找出差异。谢谢你抽出时间!

我尝试过的事情列表:

    用户代理
  • 替换cdc_在chromeDrive中的另一个字符串
  • options.add_experimental_option(不包括开关,[使能自动化])
  • options.add_experimental_option('useAutomationExent', False)
  • options.add_argument('--disable-blink-特性=AutomationControlled')(这对于在非无头环境中加载网站是必要的)
  • navigator.webdriver未定义
  • 设置navigator.pluginsnavigator.languagesnavigator.mime类型
  • 设置窗口。屏幕Ywindow.screen顶部window.outer宽度window.outer高度为非零
  • 设置window.chromewindow.navigator.chrome
  • 将图像的宽度和高度设置为非零
  • 设置WebGL参数
  • 修复现代的

复制实验

为了让网站加载正常(非无头)Selenium,你必须遵循另一个网站的_blank链接(以便目标网站在另一个选项卡中打开)。要复制实验,首先创建一个html文件,其中包含内容

下面的版本(非无头)运行良好并加载网站,但如果您设置选项。headless=True,它将卡在Cloudflare上。

from selenium import webdriver
import time

# Replace this with the path to your html file
FULL_PATH_TO_HTML_FILE = 'file:///Users/simplepineapple/html/url_page.html'

def visit_website(browser):
    browser.get(FULL_PATH_TO_HTML_FILE)
    time.sleep(3)

    links = browser.find_elements_by_xpath("//a[@href]")
    links[0].click()
    time.sleep(10)

    # Switch webdriver focus to new tab so that we can extract html
    tab_names = browser.window_handles
    if len(tab_names) > 1:
        browser.switch_to.window(tab_names[1])

    time.sleep(1)
    html = browser.page_source
    print(html)
    print()
    print()

    if 'Charts' in html:
        print('Success')
    else:
        print('Fail')

    time.sleep(10)


options = webdriver.ChromeOptions()
# If options.headless = True, the website will not load
options.headless = False
options.add_argument("--window-size=1920,1080")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument('--disable-blink-features=AutomationControlled')
options.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36')

browser = webdriver.Chrome(options = options)

browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
    "source": '''
    Object.defineProperty(navigator, 'webdriver', {
        get: () => undefined
    });
    Object.defineProperty(navigator, 'plugins', {
            get: function() { return {"0":{"0":{}},"1":{"0":{}},"2":{"0":{},"1":{}}}; }
    });
    Object.defineProperty(navigator, 'languages', {
        get: () => ["en-US", "en"]
    });
    Object.defineProperty(navigator, 'mimeTypes', {
        get: function() { return {"0":{},"1":{},"2":{},"3":{}}; }
    });

    window.screenY=23;
    window.screenTop=23;
    window.outerWidth=1337;
    window.outerHeight=825;
    window.chrome =
    {
      app: {
        isInstalled: false,
      },
      webstore: {
        onInstallStageChanged: {},
        onDownloadProgress: {},
      },
      runtime: {
        PlatformOs: {
          MAC: 'mac',
          WIN: 'win',
          ANDROID: 'android',
          CROS: 'cros',
          LINUX: 'linux',
          OPENBSD: 'openbsd',
        },
        PlatformArch: {
          ARM: 'arm',
          X86_32: 'x86-32',
          X86_64: 'x86-64',
        },
        PlatformNaclArch: {
          ARM: 'arm',
          X86_32: 'x86-32',
          X86_64: 'x86-64',
        },
        RequestUpdateCheckStatus: {
          THROTTLED: 'throttled',
          NO_UPDATE: 'no_update',
          UPDATE_AVAILABLE: 'update_available',
        },
        OnInstalledReason: {
          INSTALL: 'install',
          UPDATE: 'update',
          CHROME_UPDATE: 'chrome_update',
          SHARED_MODULE_UPDATE: 'shared_module_update',
        },
        OnRestartRequiredReason: {
          APP_UPDATE: 'app_update',
          OS_UPDATE: 'os_update',
          PERIODIC: 'periodic',
        },
      },
    };
    window.navigator.chrome =
    {
      app: {
        isInstalled: false,
      },
      webstore: {
        onInstallStageChanged: {},
        onDownloadProgress: {},
      },
      runtime: {
        PlatformOs: {
          MAC: 'mac',
          WIN: 'win',
          ANDROID: 'android',
          CROS: 'cros',
          LINUX: 'linux',
          OPENBSD: 'openbsd',
        },
        PlatformArch: {
          ARM: 'arm',
          X86_32: 'x86-32',
          X86_64: 'x86-64',
        },
        PlatformNaclArch: {
          ARM: 'arm',
          X86_32: 'x86-32',
          X86_64: 'x86-64',
        },
        RequestUpdateCheckStatus: {
          THROTTLED: 'throttled',
          NO_UPDATE: 'no_update',
          UPDATE_AVAILABLE: 'update_available',
        },
        OnInstalledReason: {
          INSTALL: 'install',
          UPDATE: 'update',
          CHROME_UPDATE: 'chrome_update',
          SHARED_MODULE_UPDATE: 'shared_module_update',
        },
        OnRestartRequiredReason: {
          APP_UPDATE: 'app_update',
          OS_UPDATE: 'os_update',
          PERIODIC: 'periodic',
        },
      },
    };
    ['height', 'width'].forEach(property => {
        const imageDescriptor = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, property);

        // redefine the property with a patched descriptor
        Object.defineProperty(HTMLImageElement.prototype, property, {
            ...imageDescriptor,
            get: function() {
                // return an arbitrary non-zero dimension if the image failed to load
            if (this.complete && this.naturalHeight == 0) {
                return 20;
            }
                return imageDescriptor.get.apply(this);
            },
        });
    });

    const getParameter = WebGLRenderingContext.getParameter;
    WebGLRenderingContext.prototype.getParameter = function(parameter) {
        if (parameter === 37445) {
            return 'Intel Open Source Technology Center';
        }
        if (parameter === 37446) {
            return 'Mesa DRI Intel(R) Ivybridge Mobile ';
        }

        return getParameter(parameter);
    };

    const elementDescriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'offsetHeight');

    Object.defineProperty(HTMLDivElement.prototype, 'offsetHeight', {
        ...elementDescriptor,
        get: function() {
            if (this.id === 'modernizr') {
            return 1;
            }
            return elementDescriptor.get.apply(this);
        },
    });
    '''
})

visit_website(browser)

browser.quit()

共有2个答案

厍华清
2023-03-14

cloudflare protection IUAM主要用于避免ddos攻击,因此它还可以保护站点免受自动化机器人攻击,因此无论您在客户端使用什么,cloudflare服务器都会对您进行指纹识别。之后,他们会向客户端发送一个cookie,允许您在接下来的15分钟内进行连接。

贲培
2023-03-14

使用最新的谷歌ChromeV96。如果检索useragent,则返回0

>

  • 对于google-chrome浏览器,正在使用以下用户代理:

    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
    

    其中,对于google chrome无头浏览器,正在使用以下用户代理:

    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/96.0.4664.110 Safari/537.36
    

    在大多数情况下,附加的Headless字符串/参数/属性的存在会被机器人拦截,云火炬会阻止对网站的访问。

    即使在无头模式下使用Chrome也有不同的方法来逃避Cloudflare检测,一些有效的方法如下:

    >

    >

  • 代码块:

    import undetected_chromedriver as uc
    from selenium import webdriver
    
    options = webdriver.ChromeOptions() 
    options.headless = True
    options.add_argument("start-maximized")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    driver = uc.Chrome(options=options)
    driver.get('https://bet365.com')
    

    您可以在以下内容中找到一些相关的详细讨论:

    • Selenium应用程序在Heroku上托管时重定向到Cloudflare页面

    >

  • 最有效的解决方案将是使用Selenium隐形来初始化Chrome浏览内容。这个节目试图让蟒蛇硒更隐蔽。

    >

  • 代码块:

    from selenium import webdriver
    from selenium_stealth import stealth
    
    options = webdriver.ChromeOptions()
    options.add_argument("start-maximized")
    options.add_argument("--headless")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=options, executable_path=r"C:\path\to\chromedriver.exe")
    
    stealth(driver,
            languages=["en-US", "en"],
            vendor="Google Inc.",
            platform="Win32",
            webgl_vendor="Intel Inc.",
            renderer="Intel Iris OpenGL Engine",
            fix_hairline=True,
            )
    
    driver.get("https://bot.sannysoft.com/")
    

    您可以在以下内容中找到一些相关的详细讨论:

    • 网站能否检测到您何时将硒与chromedriver一起使用

  •  类似资料:
    • 我正在尝试使用selenium Python访问一个站点。但是该站点正在通过cloud dflare不断检查和检查。没有其他页面来了。 检查这里的截图。 我尝试了未被发现的chrome,但它根本不起作用。

    • 我需要从一个网站获取一些信息只是为了教育的目的,但我不能发送请求,因为保护。我首先会看到典型的Checking-your-browser页面,然后我会被反复重定向。我如何在python Selenium中绕过这个保护?

    • 使用ptyhon的selenium来抓取目标站时,发现网站使用了cloudflare,用平常的手段均无法跳过,都会被屏蔽掉。

    • 问题内容: 我以前偶尔会抓取电子商务网页以获取产品价格信息。我有一段时间没有使用过使用Scrapy构建的刮板,而昨天却试图使用它-我遇到了机器人防护问题。 它使用的是CloudFlare的DDOS保护,基本上是使用JavaScript评估来过滤掉禁用了JS的浏览器(因此是抓取器)。评估功能后,将生成带有计算数字的响应。作为回报,服务会发回两个身份验证Cookie,这些身份验证Cookie附加在每个

    • 我们都知道,有时候cloudflare喜欢检查他们的客户访问者,以确保访问者不是真正的人。安全检查要求我们通过谷歌recaptcha。我想问的是,是否有可能通过使用我们自己的服务器(即使与远程服务器和回答验证码由我们自己等),以及如何?