Selenium 和非无头浏览器不断询问验证码
Selenium and non-headless browser keeps asking for Captcha
我 运行 遇到一个问题,我们的一个网站一直在云中的浏览器中以无头模式请求验证码,所以我将其切换为非无头模式,这样我就可以输入验证码了我自己,我认为下一次它会起作用,也许是因为已经存储了一些cookie,但即使我输入了几次验证码也没有。
另外值得一提的是,它 运行 在任何模式下在本地都很好,而且对于非自动版本,它在云端 运行 也很好,但是一旦我 运行 l 它与 Selenium 一起以任何模式不断询问验证码。非常感谢任何可能发生的想法和解决方案的想法
所以验证码的工作原理是,根据您执行操作的速度,它会触发一种标志,通知服务器您是 A) 试图破解网页或 B) 使其自动化。这几乎总是会产生一个验证码实例。迄今为止,还没有办法处理验证码。如果这是您公司开发的环境,您可以要求开发人员在具有不同 URL 的暂存环境中关闭验证码。这是理想情况,但如果这是一个外部站点,那么您将无能为力。
在标题为 How does recaptcha 3 know I'm using selenium/chromedriver 的讨论中,我们讨论了一些避免在 web-scraping 时被检测到的通用方法。让我们深入探讨。
无头浏览器
无头浏览器是一种无需图形界面即可使用的浏览器。它可以通过编程方式控制以自动执行任务,例如进行测试或截取网页屏幕截图。
为什么要检测无头浏览器?
根据 @AntoineVastel,无头浏览器用于自动执行恶意任务。最常见的情况是网页抓取、增加广告印象或寻找网站上的漏洞。
直到一年前,最流行的无头浏览器之一是 PhantomJS。由于它建立在 Qt 框架之上,与大多数流行的浏览器相比,它表现出许多差异。可以使用一些浏览器指纹识别技术来检测 PhantomJS。从版本 59 开始,Google 发布了其 Chrome 浏览器的无头版本。与 PhantomJS 不同,它基于 vanilla Chrome,而不是基于外部框架,这使得它的存在更难被发现。所以可能还有其他方法可以检测 Chrome headless.
检测Chrome无头
User agent: user agent属性常用于检测OS以及用户的浏览器。对于 Chrome 版本 59,它具有以下值:
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/59.0.3071.115 Safari/537.36
检查是否存在 Chrome headless 可以通过以下方式完成:
if (/HeadlessChrome/.test(window.navigator.userAgent)) {
console.log("Chrome headless detected");
}
Plugins: navigator.plugins
returns 浏览器中存在的一组插件.通常,在 Chrome 上我们会找到默认插件,例如 Chrome PDF viewer
或 Google Native Client
。相反,在无头模式下,返回的数组包含 no plugin.
可以通过以下方式检查 插件 是否存在:
if(navigator.plugins.length == 0) {
console.log("It may be Chrome headless");
}
Languages:在Chrome中有两个Javascript属性可以获取[=20使用的语言=] 和 navigator.languages
。第一个是浏览器的语言 UI,而第二个是表示用户首选语言的字符串数组。但是,在无头模式下,navigator.languages
returns 一个 空 字符串。
可以通过以下方式检查 语言 是否存在:
if(navigator.languages == "") {
console.log("Chrome headless detected");
}
WebGL:WebGL 是 API 在 HTML canvas 中执行 3D 渲染。使用此 API,可以查询图形 driver 的供应商以及图形 driver 的渲染器。使用 vanilla Chrome 和 Linux,我们可以获得渲染器和供应商的以下值:Google SwiftShader
和 Google Inc.
。在无头模式下,我们可以获得Mesa OffScreen
,这是用于渲染的技术,无需使用任何类型的window系统和Brian Paul
,这是启动开源Mesa图形库的程序。
可以通过以下方式检查是否存在 WebGL:
var canvas = document.createElement('canvas');
var gl = canvas.getContext('webgl');
var debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
var vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
if(vendor == "Brian Paul" && renderer == "Mesa OffScreen") {
console.log("Chrome headless detected");
}
并非所有 Chrome headless 都具有相同的供应商和渲染器值。其他人保留也可以在非无头版本上找到的值。但是,Mesa Offscreen
和Brian Paul
表示无头版本的存在。
浏览器功能:Modernizr 库可以测试浏览器中是否存在大量 HTML 和 CSS 功能.我们发现 Chrome 和 headless Chrome 之间的唯一区别是后者没有 hairline 功能,它检测对 hidpi/retina hairlines
.
检查是否存在 细线特征 可以通过以下方式完成:
if(!Modernizr["hairline"]) {
console.log("It may be Chrome headless");
}
缺少图像:我们列表中的最后一个似乎也是最稳健的,来自 Chrome 使用的图像的维度以防无法加载图像。在香草 Chrome 的情况下,图像的宽度和高度取决于浏览器的缩放比例,但不同于零。在无头 Chrome 中,图像的宽度和高度都为零。
可以通过以下方式检查是否存在 缺失图像 :
var body = document.getElementsByTagName("body")[0];
var image = document.createElement("img");
image.src = "http://iloveponeydotcom32188.jg";
image.setAttribute("id", "fakeimage");
body.appendChild(image);
image.onerror = function(){
if(image.width == 0 && image.height == 0) {
console.log("Chrome headless detected");
}
}
这些是无头浏览器更容易被检测到的一些关键因素。
结尾
我 运行 遇到一个问题,我们的一个网站一直在云中的浏览器中以无头模式请求验证码,所以我将其切换为非无头模式,这样我就可以输入验证码了我自己,我认为下一次它会起作用,也许是因为已经存储了一些cookie,但即使我输入了几次验证码也没有。
另外值得一提的是,它 运行 在任何模式下在本地都很好,而且对于非自动版本,它在云端 运行 也很好,但是一旦我 运行 l 它与 Selenium 一起以任何模式不断询问验证码。非常感谢任何可能发生的想法和解决方案的想法
所以验证码的工作原理是,根据您执行操作的速度,它会触发一种标志,通知服务器您是 A) 试图破解网页或 B) 使其自动化。这几乎总是会产生一个验证码实例。迄今为止,还没有办法处理验证码。如果这是您公司开发的环境,您可以要求开发人员在具有不同 URL 的暂存环境中关闭验证码。这是理想情况,但如果这是一个外部站点,那么您将无能为力。
在标题为 How does recaptcha 3 know I'm using selenium/chromedriver 的讨论中,我们讨论了一些避免在 web-scraping 时被检测到的通用方法。让我们深入探讨。
无头浏览器
无头浏览器是一种无需图形界面即可使用的浏览器。它可以通过编程方式控制以自动执行任务,例如进行测试或截取网页屏幕截图。
为什么要检测无头浏览器?
根据 @AntoineVastel,无头浏览器用于自动执行恶意任务。最常见的情况是网页抓取、增加广告印象或寻找网站上的漏洞。
直到一年前,最流行的无头浏览器之一是 PhantomJS。由于它建立在 Qt 框架之上,与大多数流行的浏览器相比,它表现出许多差异。可以使用一些浏览器指纹识别技术来检测 PhantomJS。从版本 59 开始,Google 发布了其 Chrome 浏览器的无头版本。与 PhantomJS 不同,它基于 vanilla Chrome,而不是基于外部框架,这使得它的存在更难被发现。所以可能还有其他方法可以检测 Chrome headless.
检测Chrome无头
User agent: user agent属性常用于检测OS以及用户的浏览器。对于 Chrome 版本 59,它具有以下值:
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/59.0.3071.115 Safari/537.36
检查是否存在 Chrome headless 可以通过以下方式完成:
if (/HeadlessChrome/.test(window.navigator.userAgent)) { console.log("Chrome headless detected"); }
Plugins:
navigator.plugins
returns 浏览器中存在的一组插件.通常,在 Chrome 上我们会找到默认插件,例如Chrome PDF viewer
或Google Native Client
。相反,在无头模式下,返回的数组包含 no plugin.可以通过以下方式检查 插件 是否存在:
if(navigator.plugins.length == 0) { console.log("It may be Chrome headless"); }
Languages:在Chrome中有两个Javascript属性可以获取[=20使用的语言=] 和
navigator.languages
。第一个是浏览器的语言 UI,而第二个是表示用户首选语言的字符串数组。但是,在无头模式下,navigator.languages
returns 一个 空 字符串。可以通过以下方式检查 语言 是否存在:
if(navigator.languages == "") { console.log("Chrome headless detected"); }
WebGL:WebGL 是 API 在 HTML canvas 中执行 3D 渲染。使用此 API,可以查询图形 driver 的供应商以及图形 driver 的渲染器。使用 vanilla Chrome 和 Linux,我们可以获得渲染器和供应商的以下值:
Google SwiftShader
和Google Inc.
。在无头模式下,我们可以获得Mesa OffScreen
,这是用于渲染的技术,无需使用任何类型的window系统和Brian Paul
,这是启动开源Mesa图形库的程序。可以通过以下方式检查是否存在 WebGL:
var canvas = document.createElement('canvas'); var gl = canvas.getContext('webgl'); var debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); var vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL); var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); if(vendor == "Brian Paul" && renderer == "Mesa OffScreen") { console.log("Chrome headless detected"); }
并非所有 Chrome headless 都具有相同的供应商和渲染器值。其他人保留也可以在非无头版本上找到的值。但是,
Mesa Offscreen
和Brian Paul
表示无头版本的存在。
浏览器功能:Modernizr 库可以测试浏览器中是否存在大量 HTML 和 CSS 功能.我们发现 Chrome 和 headless Chrome 之间的唯一区别是后者没有 hairline 功能,它检测对
hidpi/retina hairlines
.检查是否存在 细线特征 可以通过以下方式完成:
if(!Modernizr["hairline"]) { console.log("It may be Chrome headless"); }
缺少图像:我们列表中的最后一个似乎也是最稳健的,来自 Chrome 使用的图像的维度以防无法加载图像。在香草 Chrome 的情况下,图像的宽度和高度取决于浏览器的缩放比例,但不同于零。在无头 Chrome 中,图像的宽度和高度都为零。
可以通过以下方式检查是否存在 缺失图像 :
var body = document.getElementsByTagName("body")[0]; var image = document.createElement("img"); image.src = "http://iloveponeydotcom32188.jg"; image.setAttribute("id", "fakeimage"); body.appendChild(image); image.onerror = function(){ if(image.width == 0 && image.height == 0) { console.log("Chrome headless detected"); } }
这些是无头浏览器更容易被检测到的一些关键因素。