专栏首页Urlteam反爬虫之检测PhantomJS访客(翻译文)

反爬虫之检测PhantomJS访客(翻译文)

翻译前言:作为数据采集工程师经常和反爬虫技术做斗争,其中我使用的爬虫结构是:分布式+多机器+adsl | tor+phantomjs无界面浏览器+机器学习验证码破解/这样的结构已经基本属于爬虫界的大招。但是对方如果通过检测phantomjs的浏览器特性还是能区别出爬虫。于是翻译本文知己知彼,翻译功底不好切勿见怪,高手请移步文尾部可以看英语原文。

这些天,许多web安全事故涉及自动化。 Web-scraping、密码重用和点击欺诈攻击对手试图模拟真实用户,从而将请求看起来像是来自一个浏览器。作为网站的所有者,你想确保你的web是为人类服务。假设你有基本的检查cURL-like访客的能力,下一个合理的步骤是确保访客使用的是真正的ui驱动浏览器——而不是无头浏览器 PhantomJS SlimerJS 。在本文中,我们将展示一些PhantomJS检测的技术。 我们决定专注于PhantomJS因为它是最受欢迎的无头浏览器环境,但许多的概念,我们将讨论适用于SlimerJS和其他工具。

注意:在本文中介绍的技术适用于PhantomJS 1。 x和2。 x,除非明确提及。

目录:

  1. HTTP栈
  2. 客户端User-Agent 检查
  3. 使用插件
  4. 定时
  5. 全局属性
  6. 缺乏JavaScript引擎的功能
  7. 堆栈跟踪

1: 检查HTTP栈

首先:它可以检测PhantomJS甚至在不用相应他(在获取请求头就可以检测他)吗?

如你所知,PhantomJS是建立在 Qt框架 。 Qt实现HTTP栈的方式使它突出于其他现代浏览器。

首先,让我们看看Chrome,发出以下head:

GET / HTTP/1.1
Host: localhost:1337
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,ru;q=0.6

然而在PhantomJS,相同的HTTP请求是这样的:

GET / HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.9.8 Safari/534.34
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: Keep-Alive
Accept-Encoding: gzip
Accept-Language: en-US,*
Host: localhost:1337

你会注意到PhantomJS头是不同于Chrome(事实证明,其他所有现代浏览器)有一些微妙的不同:

  • 主机(host) 出现最后一行
  • 连接头(Connection)是大小写混合
  • 唯一的 接受编码 值是gzip
  • User-Agent 包含“PhantomJS”

在服务器上检查这些HTTP头的变化,它应该可以识别PhantomJS浏览器。

但是,相信这些值安全吗? 如果敌人使用一个代理修改标题前面的无头浏览器,他们可以修改这些标题显得象一个正常的现代浏览器。

看来解决这个问题纯粹只是在服务器上不是合适的。 让我们看看能做些什么在客户端,现在使用PhantomJS的JavaScript环境。

2: 客户端User-Agent 检查

我们可能无法通过HTTP信任User-Agent 的值但是在客户端呢?

if (/PhantomJS/.test(window.navigator.userAgent)) {
    console.log("PhantomJS environment detected.");
}

不幸的是,它同样是可以被改变User-Agen和head 在PhantomJS 中检测userAgent值,这可能是不够的。

3: 使用插件

navigator.plugins 包含一个数组的插件在浏览器内。 典型的插件的价值观包括Flash,ActiveX,支持Java applet,“ 默认浏览器助手 ”,这是一个插件,表明这个浏览器是OS x的默认浏览器是否在我们的研究中,大多数新安装的常见的浏览器包括至少一个默认插件。

这是与PhantomJS,不实现任何插件,也不提供一种方法来添加一个(使用 PhantomJS API )。

以下检查可能会是有用的:

if (!(navigator.plugins instanceof PluginArray) || navigator.plugins.length == 0) {
    console.log("PhantomJS environment detected.");
} else {
    console.log("PhantomJS environment not detected.");
}

另一方面,恶搞这个插件很简单数组通过修改PhantomJS JavaScript环境 在页面加载之前

也不难想象一个自定义构建的PhantomJS真实,实现插件。 这比听起来要容易得多,因为Qt PhantomJS构建提供了一个框架 本机API 实现插件。

4: 定时

另一个感兴趣的点是如何PhantomJS抑制JavaScript对话框:

var start = Date.now();
alert('Press OK');
var elapse = Date.now() - start;
if (elapse < 15) {
    console.log("PhantomJS environment detected. #1");
} else {
    console.log("PhantomJS environment not detected.");
}

多次测量后,似乎如果警告对话框被限制了在15毫秒,浏览器可能不是被一个真实的人控制。 但使用这种方法意味着困扰真实用户与一个警告他们会手动关闭。

5: 全局属性

PhantomJS 1。 x暴露在全局对象两个属性:

if (window.callPhantom || window._phantom) {
  console.log("PhantomJS environment detected.");
} else {
  console.log("PhantomJS environment not detected.");
}

然而,这些属性的一部分 实验功能 和在未来可能会改变。

6: 缺乏JavaScript引擎的功能

PhantomJS 1. x和2. x目前使用过时的WebKit引擎,这意味着有浏览器特性中存在的新浏览器PhantomJS并不存在。 这延伸到JavaScript引擎——即一些本机属性和方法是不同的或在PhantomJS缺席。其中一个方法是Function.prototype。 绑定,PhantomJS 下面的示例检查是否存在绑定,它没有被欺骗的执行环境。

(function () {
  if (!Function.prototype.bind) {
    console.log("PhantomJS environment detected. #1");
    return;
  }
  if (Function.prototype.bind.toString().replace(/bind/g, 'Error') != Error.toString()) {
    console.log("PhantomJS environment detected. #2");
    return;
  }
  if (Function.prototype.toString.toString().replace(/toString/g, 'Error') != Error.toString()) {
    console.log("PhantomJS environment detected. #3");
    return;
  }
  console.log("PhantomJS environment not detected.");
})();

这段代码是有点太棘手的详细解释,但你可以找到更多 我们的演示

7: 堆栈跟踪

错误抛出的JavaScript代码由PhantomJS通过评估 评估 命令包含一个堆栈跟踪的唯一标识,我们可以确定无头浏览器。

例如,假设PhantomJS评估以下代码:

var err;
try {
  null[0]();
} catch (e) {
  err = e;
}
if (indexOfString(err.stack, 'phantomjs') > -1) {
  console.log("PhantomJS environment detected.");
} else {
  console.log("PhantomJS environment is not detected.");
}

注意,这个示例使用一个定制的 indexOfString() 函数,留给读者作为练习,因为本机String.prototype.indexOf 可以欺骗PhantomJS总是返回一个负面的结果。

现在,你如何让PhantomJS脚本评价这段代码? 技术之一是覆盖一些经常使用DOM API函数可能被称为。 例如,下面的代码覆盖 document.querySelectorAll 检查浏览器的堆栈跟踪:

var html = document.querySelectorAll('html');
var oldQSA = document.querySelectorAll;
Document.prototype.querySelectorAll = Element.prototype.querySelectorAll = function () {
  var err;
  try {
    null[0]();
  } catch (e) {
    err = e;
  }
  if (indexOfString(err.stack, 'phantomjs') > -1) {
    return html;
  } else {
    return oldQSA.apply(this, arguments);
  }
};

总结

在本文中,我们研究了7个不同的技术来识别PhantomJS,都在服务器上,执行代码PhantomJS的客户端JavaScript环境。 结合检测结果与一个强大的反馈机制——例如,呈现动态页面惰性或无效当前会话cookie——你可以获得一个坚实的阻止PhantomJS访客的防火墙。 然而,总是记住这些技术并不可靠,和一个复杂的对手最终将获得通过。

为了了解更多,我们建议看的记录 从2014年美国AppSec我们的演示 ( 幻灯片 )。 我们也放在一起 GitHub库 实现示例和可能的危害,本文提供的技术。

感谢你的阅读,快乐狩猎。

Contributors

链接分享:

网址原文 翻译文GitHub库

原创文章,转载请注明: 转载自URl-team

本文链接地址: 反爬虫之检测PhantomJS访客(翻译文)

  1. Scrapy-笔记一 入门项目 爬虫抓取w3c网站
  2. Scrapy笔记四 自动爬取网页之使用CrawlSpider
  3. Scrapy笔记五 爬取妹子图网的图片 详细解析
  4. 运用基于内存的数据库redis构建分布式爬虫–抓妹子图网
  5. SCRAPY学习笔记九 增量爬取url 使用 yield 的用法
  6. 爬虫破解IP限制–ADSL动态IP服务器–部署小结

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 通过python在两台linux服务器间传递文件

    python -m SimpleHTTPServer 可以开启一个http服务器,默认端口是8000,-m选项指示python将module作为脚本运行。这样...

    十四君
  • python-pep8 编码规范

    一 代码编排 1 缩进。4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。 2 每行最大长度79,换行可以使用反斜杠,最好...

    十四君
  • c语言函数库学习~sscanf~格式化输入

    今天算是被打击到了吧,由郑轻的acm老师来我学院指导安排了个现场的小比赛,,俺们居然有还是输给一个大一的新手,,哎,情何以堪,,所以还是要重视下基础编程能力的培...

    十四君
  • 小程序开发基础-view视图容器

    查看官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/

    达达前端
  • C#数组

    这样就声明了一个数组(声明数组,而非定义)。接着就该给声明好的数组分配内存了,由于C#里数组是引用类型,因此应当使用new运算符来分配内存,这个时候应当指出数组...

    zy010101
  • B4A 调用谷歌翻译api进行翻译

    Google 翻译是谷歌公司提供一项免费的翻译服务,可提供103 种语言之间的即时翻译,支持任意两种语言之间的字词、句子和网页翻译。可分析的人工翻译文档越多,译...

    巴西_prince
  • Dubbo 的负载均衡策略:最小活跃调用策略

    最小活跃调用策略:指的是当请求调用来临,有多个实例提供服务的时候,选择其中被调用活跃次数最少的实例来提供服务。通俗一点讲就是,当前有 3 个实例在提供服务,A ...

    LieBrother
  • innodb锁机制探究(二)---间隙锁(1)

    其中Next key锁是Gap锁和Record锁的结合,他锁定的是一个范围,并且锁定记录本身。

    AsiaYe
  • 《赢》第18章 糟糕的老板

    yeedomliu
  • innodb锁机制探究(二)---间隙锁(2)

    上一篇文章中,我们已经知道innodb中的间隙锁是对普通索引记录的间隙做的一个锁定动作,这篇文章我们分析下间隙锁在唯一索引中的应用。

    AsiaYe

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动