无头浏览器 PhantomJS

无头浏览器(Headless browser)指没有用户图形界面的(GUI)的浏览器,目前广泛运用于web爬虫和自动化测试中。随着反爬虫和反反爬虫对抗技术的升级,越来越多的爬虫开始使用无头浏览器伪装成正常用户绕过反爬虫策略。

我们如何区分这些无头浏览器和正常浏览器?从Server Side分析用户行为进行检测是一劳永逸的方法,但成本和难度都很大。

不过通过无头浏览器的一些特性。我们也可以从从Client Side找出一些不同来。下面以醉受欢迎的PhantomJS(2.x版本)为例,介绍一些识别的方法,对于其他的无头浏览器,如Slimer JS这些方法也可以参考

HTTP Header

  • PhantomJS
  • Chrome
  • IE 11
  • Firefox
  • 可以看出PhantomJS的请求头和其他浏览器还是有一些区别的
    • Host头在最后边
    • Connection头的值Keep-Alive是大小写混合
    • User-Agent头里包含PhantomJS关键字

检测方案

  • 通过User-Agent,可以简单的识别出一部分PhantomJS浏览器:
  • 浏览器插件

    • 另外也可以定制自己的 PhantomJS,其实并不复杂,因为 PhantomJS 是基于 Qt 框架的,而 Qt 已经提供了原生的 API 供实现插件。
  • 操作时

    般用无头浏览器的爬虫为了防止阻塞都会自动关闭页面上的对话框,但它关闭的速度肯定比正常人手动关闭快很多 ,所以我们可以通过对话框被关闭的用时来判断对面是否是机器人

  • 窗口特征

    • 不过这样在 Chrome 里会有一个 bug,当页面在隐藏选项卡中加载,例如从上一个会话恢复时,页面的 outerWidthouterHeight 也会为 0。
    • 另外可以检查键盘、鼠标、触摸屏交互,通过 onmouseoveronkeydown 等函数来判断对方是不是真实用户。
    • 但是 PhantomJS 也提供了 sendEvent 这个函数向页面发送事件
    • 还可以使用 jQuery 的 trigger() 主动触发事件:

  • 全局属性
    • PhantomJS 提供了两个全局属性:window.callPhantomwindow._phantom

    • 不过这两个是实验性功能,未来很可能会被替换。
    • 当然也可以通过重写绕过

    • 其他一些 JavaScript 引擎的独有全局属性

  • HTML5 和 JavaScript 新特性
    • PhantomJS 使用的 Webkit 引擎相对较旧,这意味着很多新浏览器才支持的特性可能在 PhantomJS 中缺失。
      • WebAudio
      • WebRTC
      • WebSocket
      • WebGL
      • FileAPI
      • CSS 3
      • Device APIs
      • BatteryManager
    • 另外,JavaScript 引擎的一些原生方法和属性在PhantomJS中不一样或者不存在

  • 堆栈追踪
    • 这是最有用的识别方法。因为开发者不可能花费大量的精力去修改Webkit的JavaScript引擎核心代码,使PhantomJS的堆栈跟踪写信和真是浏览器一样。
    • 当 PhantomJS 的 evaluate 方法报错时,它会产生独特的堆栈跟踪信息:

反击

  • 如果检测出对方使用了 PhantomJS,除了封他 IP,还有什么办法惩罚他呢? 由于 PhantomJS 2.x 已经支持 WebSocket,我们可以给他来个 WebSocket DDos 尝尝

  • 如果权限够大,我们甚至可以读取运行 PhantomJS 的机器的密码。
  • 根据 PhantomJS 开发组的计划,WebRTC 将会被支持,到时候我们还能探测他的真实 IP和扫描他的内网。

总结

文中我们介绍了一些在 Client Side 检查 PhantomJS 的方法,对于一般的 PhantomJS 爬虫具有不错的识别效果。 当然,我们不能完全依赖于这些检测手段。对于有经验的爬虫作者,他们还是能通过 Hook JavaScript 代码绕过 Client Side 的检查。比如,重写 indexOf 函数,使 err.stack.indexOf('phantomjs') 恒为 -1,从而绕过我们对堆栈跟踪的检查。

在安全方面,当我们在生产环境使用无头浏览器时,应注意环境隔离,使用低权限运行,设置 --web-security=true

市面上常见的无头浏览器

软件名 介绍 支持语言
Awesomium 基于Chromium无图形界面浏览器引擎。 C++, .NET
benv Benv是node.js开发的无界面浏览器测试环境,用于测试客户端代码。 JavaScript
browser-launcher Browser-Launcher可以检测系统上的所有浏览器版本,并在一个独立的配置文件中启动它们,用于自动测试。 JavaScript
browser.rb 无界面 Ruby 浏览器。 Ruby
Browserjet 无界面webkit浏览器,采用node.js接口。 JavaScript
BrowserKit 可模拟浏览器的行为。 PHP
CasperJS CasperJS 是一个开源的导航脚本和测试工具,使用 JavaScript 基于 PhantomJS 编写,用于测试 Web 应用功能,Phantom JS是一个服务器端的 JavaScript API 的 WebKit。其支持各种Web标准: DOM 处理, CSS 选择器, JSON, Canvas, 和 SVG。 JavaScript
DalekJS DalekJS 是一个基于 JavaScript(或 Node.js) 的免费和开源的自动化测试接口。它能够同时运行测试一组流行的浏览器(Chrome,IE,Firefox 和 WebKit)。 JavaScript
Erik Erik是一款基于WebKit的无界面浏览器,可用于功能函数的测试,使用JavaScript对网页进行操作访问。 Swift
Geb Geb 是浏览器自动化(browser automation)测试解決方案。 Groovy
ghost.py ghost.py 是一个 Python 的 Webkit 的 Web 客户端。 Python
Ghostbuster Ghostbuster 是一款自动化浏览器测试工具,基于phantomjs,意味着你得到一个仿真浏览器,一个真正的DOM,仿真测试环境。 JavaScript
grope Grope 是无GUI浏览器环境,使用WebKit Framework + RubyCocoa。 Ruby
Guillotine Guillotine 是一款采用C#开发的.NET 无界面浏览器。 .NET
Headless Headless是一款无界面浏览器,支持快速网络接受测试,采用.Net环境。 .NET
headless_browser Headless-Browser 是一款采用C++开发的基于WebKit 无界面浏览器。 C++
HeadlessBrowser HeadlessBrowser是一款轻量级无图形界面浏览器,用于DOM测试。 JavaScript
HtmlUnit HtmlUnit 是一个is a “Java 程序 GUI-Less 浏览器”。 Java
Jabba-Webkit Jabba-Webkit是一款无图形化 WebKit 浏览器,主要用来抓取Ajax网页。 Python
Jasmine-Headless-Webkit Jasmine-Headless-Webkit是一款基于jasmine的无图形化web工具。 Python, JavaScript, Ruby
Jaunt Java Web 网页抓取&自动化 API Java
jBrowserDriver jBrowserDriver是一款采用纯Java编写的无图形化浏览器,基于WebKit,和Selenium兼容。 Java
jedi-crawler Jedi-Crawler 是一款轻量级 Node/PhantomJS爬虫,可以动态的抓取网页内容。 JavaScript
Lotte Lotte是一款自动化无图形化浏览器测试工具,采用phantomJs。 JavaScript
MechanicalSoup MechanicalSoup是一个与网站自动交互Python库。 Python
mechanize 状态编程的Web浏览。 Python
Nightmare 高层次浏览器自动化库,构建于PhantomJS。 JavaScript
PhantomJS Phantom JS是一个服务器端的 JavaScript API 的 WebKit JavaScript, Python, Ruby, Java, C#, Haskell, Objective-C, Perl, PHP, R(via Selenium)
phantompy Phantompy 是一款headless WebKit 引擎,构建于强大的 Qt5 Webkit API之上。 Python
Python-Webkit Python-Webkit 是一个Webkit python扩展, 可完整的访问网页的DOM。 Python
RoboBrowser RoboBrowser 是一款简单的浏览网页的Pythonic库,无需依赖独立的浏览器。 Python
Selenium 跨平台自动化web浏览器。 JavaScript, Python, Ruby, Java, C#, Haskell, Objective-C, Perl, PHP, R
SimpleBrowser SimpleBrowser是专门为自动化任务而设计的一个灵活而直观的浏览器引擎,内置.Net 4 framework。 .NET
SlimerJS SlimerJS 是一个提供给 Web 开发人员,可通过脚本编程控制的浏览器。 JavaScript
Splash Splash是一款HTTP API 轻量级浏览器,采用Python和QT开发。 Any
Splinter Splinter 是一个用 Python 编写的 Web 应用程序进行验收测试的工具。 Python
Spynner Spynner是一个可编程Web浏览器Python模块。支持AJAX Python
SST SST (selenium-simple-test) 是一个 Web 测试框架,使用 Python 来生成基于浏览器的功能测试。 Python
stanislaw Stanislaw一款Python headless 浏览器测试工具。 Python
trifleJS 一个 headless IE 浏览器。采用 .NET WebBrowser类,拥有Javascript API,运行在 V8引擎。 JavaScript
twill Twill是一种简单的语言,允许用户通过一个命令行界面浏览网页。 Python
WatiN Watin是一个面向.net的Web自动化测试开源项目,对应Web元素提供了丰富的类库,而且使用起来非常简单。 .NET
Watir-WebDriver Watir的实现基于WebDriver的Ruby绑定。 Ruby
WKZombie WKZombie是针对iOS/ OSX的不需要用户界面或API就能进行网站导航和数据收集的一个Swift框架,也被称为无界面浏览器。 Swift
Zombie.js 一个轻量级的框架,用于在一个模拟的环境中测试客户端的 JavaScript 代码。Zombie.js 使用 Node.js 实现快速的 headless full-stack 测试平台。 JavaScript

承接各种网站开发与修改、爬虫、数据采集分析、小程序等任务

Html+Css+JS+PHP+Nodejs+Python

专治网站各种不服

一起探讨,互相学习,共同进步!有事儿您说话。

This entry was posted in C/C++, JavaScript, NodeJS and tagged , by 织梦先生. Bookmark the permalink.