selenium - Selenium 和非无头浏览器不断要求验证码
问题描述
我遇到了一个问题,我们的一个网站一直在云中的浏览器中以无头模式要求验证码,所以我将其切换为非无头模式,这样我就可以自己输入验证码,我想下次它会工作,也许是因为已经存储了一些cookie,但即使我输入了几次验证码,它也没有。
另外值得一提的是,它在任何模式下都可以在本地运行,并且在非自动化版本的云中也可以很好地运行,但是只要我在 Selenium 那里以任何模式运行它,它就会一直要求验证码。非常感谢任何可能发生的想法和解决方案的想法
解决方案
在题为“recaptcha 3 如何知道我正在使用 selenium/chromedriver ”的讨论中,我们讨论了一些通用方法以避免在网络抓取时被检测到。让我们深入了解一下。
无头浏览器
无头浏览器是可以在没有图形界面的情况下使用的浏览器。它可以通过编程方式控制以自动执行任务,例如进行测试或截取网页截图。
为什么要检测无头浏览器?
根据@AntoineVastel,无头浏览器用于自动执行恶意任务。最常见的情况是网页抓取、增加广告印象或在网站上寻找漏洞。
直到一年前,最流行的无头浏览器之一是 PhantomJS。由于它是基于 Qt 框架构建的,因此与大多数流行的浏览器相比,它表现出许多不同之处。可以使用一些浏览器指纹技术检测 PhantomJS。从 59 版开始,Google 发布了 Chrome 浏览器的无头版本。与 PhantomJS 不同,它基于原生 Chrome,而不是外部框架,因此更难检测到它的存在。因此,可能还有其他方法可以检测 Chrome 无头。
检测 Chrome 无头
用户代理:用户代理属性通常用于检测操作系统以及用户的浏览器。对于 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
返回浏览器中存在的插件数组。通常,在 Chrome 上我们会找到默认插件,例如Chrome PDF viewer
或Google Native Client
。相反,在无头模式下,返回的数组不包含插件。可以通过以下方式检查插件是否存在:
if(navigator.plugins.length == 0) { console.log("It may be Chrome headless"); }
语言:在 Chrome 中,两个 Javascript 属性可以获取
user: navigator.language
和使用的语言navigator.languages
。第一个是浏览器 UI 的语言,而第二个是表示用户首选语言的字符串数组。但是,在无头模式下,navigator.languages
返回一个空字符串。可以通过以下方式检查语言是否存在:
if(navigator.languages == "") { console.log("Chrome headless detected"); }
WebGL:WebGL 是一种在 HTML 画布中执行 3D 渲染的 API。使用此 API,可以查询图形驱动程序的供应商以及图形驱动程序的渲染器。使用 vanilla Chrome 和 Linux,我们可以获得以下渲染器和供应商的值:
Google SwiftShader
和Google Inc.
. 在无头模式下,我们可以获得Mesa OffScreen
,这是用于在不使用任何类型的窗口系统的情况下进行渲染的技术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 的供应商和渲染器都具有相同的值。其他人保留在非无头版本上也可以找到的值。但是,
Mesa Offscreen
并Brian Paul
表示存在无头版本。
浏览器功能:Modernizr 库可以测试浏览器中是否存在各种 HTML 和 CSS 功能。我们发现 Chrome 和无头 Chrome 之间的唯一区别是后者没有细线功能,该功能检测对
hidpi/retina hairlines
.可以通过以下方式检查是否存在细线特征:
if(!Modernizr["hairline"]) { console.log("It may be Chrome headless"); }
Missing image:我们列表中的最后一个似乎也是最强大的,来自 Chrome 使用的图像尺寸,以防图像无法加载。在 vanilla 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"); } }
这些是无头浏览器更容易被检测到的一些关键因素。
奥特罗
推荐阅读
- javascript - VueJs - 带有多选复选框和带有值的文本字段的选项数组
- javascript - 使用应用程序脚本在数组中具有唯一的名称集,没有空白表名称
- python - 1D CNN 模型的 Tensor Sequential 模型接收到的维度错误
- ios - 为什么我的视图没有更新我发布的变量?
- python - 删除 '',''' 之后的值
- rust - 错误[E0463]:找不到“core”的板条箱/注意:可能未安装“wasm32-unknown-unknown”目标[NEAR 协议]
- python - 将整数转换为一对字节会产生意外的格式?
- c - 用户输入的精确时间
- java - MyBatis oracle 插入新行总是返回错误的主 id 值
- python - 在 Wagtail 仪表板上添加一个按钮以导出到 csv/xlsx 文件