背景

Selenium 是一个Web自动化测试的组件,可基于WebDriver去控制弹出浏览器去做一系列Web点击或行为测试(当然也可以去做一些邪恶的事。。),减少重复人工网页测试的开销。BrowserMobProxy相当于一层代理,它配合Selenium使用可以在Selenium控制浏览器访问之前在代理层拦截做出一些记录(har)、修改等。

一般来说,直接使用Selenium就足够了,但是Selenium有个很致命的问题是不支持修改request的参数,比如很重要的headers。headers其实是一些模拟测试时用来模拟不同的访问和测试安全的重要元信息,从一些github issues看Selenium开发方似乎拒绝考虑加入headers修改功能,以自动化测试组件不应该让用户修改headers的理由应付用户,并让大家使用BrowserMobProxy去模拟。如果webdriver也是可控的,这完全是可以做到的,可能会需要协调不同浏览器的webdriver开发者会有点麻烦;所以也不知道是开发方懒,还是和browsermobproxy的开发方有什么关系。。而弹出浏览器并能提供足够的控制功能的框架目前暂没见到其他能与selenium媲美的。(PhantomJS是在服务端提供了个解析,但并不会事实弹出浏览器模仿真正的浏览器行为,也就是说一些前端涉及鼠标、悬停等事件的脚本并不能支持)

介绍一下Selenium3.x里几个概念:

  • WebDriver:可以理解为连接不同浏览器的驱动程序,比如chrome和firefox的webdriver是不同的,如果selenium相关包没有引入你的浏览器,就要考虑去寻找了。内置支持的浏览器参见github。像IE这种需要windows相关组件支持可参考官网配置步骤。
  • Selenium IDE:其实就是个可视化的测试案例创建管理的组件,一般我们用selenium可能是写代码,但部分没那么复杂的测试功能可以通过该IDE去配置,也降低了QC的门槛。使用代码去模拟测试的可忽略IDE的存在。
  • Selenium Server:一般只会在远程测试的时候需要。比如公司有台测试机,你想要在上面测试但又不能在上面直接开发,你就可以在测试机起SeleniumServer,本地测试代码通过RemoteWebDriver的形式去连接它。大多数情况下本地测试可以忽略这个server的存在。

BrowserMobProxy会提供一个ProxyServer用于做转发代理拦截,这个server可以是standalone部署支持远程,也可以embed进代码中。由于BrowserMob是Java开发的,因此JVM的可以支持真正的embedded,python等非JVM系的只能配置其执行路径通过子进程的方式来伪装embedded,这就是AutomatedTester/browsermob-proxy-py项目中需要配置 /path/to/browsermobproxy 的原因。

使用

Selenium WebDriver的具体使用请参考网上的教程示例和官方文档,此处不赘述。

BrowserMobProxy官方文档里有段 use with selenium 的代码示例其实就是 embedded browsermob  + local selenium :

 // start the proxy
BrowserMobProxy proxy = new BrowserMobProxyServer();
proxy.start(0); // set custom headers
proxy.addHeaders(headers); // get the Selenium proxy object
Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy); // configure it as a desired capability
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.PROXY, seleniumProxy); // start the browser up
WebDriver driver = new FirefoxDriver(capabilities); // open yahoo.com
driver.get("http://yahoo.com");

需留意的是,Firefox的webdriver有坑,貌似Firefox>=52.0版本的需要用最新的Selenium和最新的Webdriver(3.3.0+)。本文主要以Java的代码为示例,python用法也类似(需先 pip install browsermob-proxy)。

remote browsermob + local selenium

        executeCMD(String.format("curl -X POST -d 'port=%d' http://localhost:8080/proxy", 55555));
executeCMD(String.format("curl -X POST -H \"Content-disposition:json/application\" - H \"Content-type:json/application\" -d '%s' http://localhost:8080/proxy/" + (port1) + "/headers", headersJson)); // get the Selenium proxy object
String PROXY = "localhost:8080";
Proxy seleniumProxy = ClientUtil.createSeleniumProxy(new InetSocketAddress("localhost", 8080));
seleniumProxy.setHttpProxy(PROXY).setSslProxy(PROXY); // configure it as a desired capability
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(CapabilityType.PROXY, seleniumProxy); // start the browser up
WebDriver driver = new ChromeDriver(capabilities);

即browsermob在外部起,本地只能通过restful与其通信,包括先注册端口和设置headers等,seleniumProxy也得配置到对应的socket去。部署browsermob也很简单,http://bmp.lightbody.net/ 下载部署版本或从github下载项目tag版本命令行执行 mvn clean package -U 源码安装。源码安装的话在browsermob-dist/target/ 下可以找到bin结尾的目录,里面就是可执行文件(*nix和windows bat都有),copy到你需要的目录即可。

embedded browsermob + remote selenium server

BrowserMobProxy proxyServer = new BrowserMobProxyServer();
proxyServer.addHeaders(headers);
proxyServer.start(port);
String PROXY = "localhost:" + port;
Proxy seleniumProxy = ClientUtil.createSeleniumProxy(new InetSocketAddress("localhost", port));
seleniumProxy.setHttpProxy(PROXY).setSslProxy(PROXY); // configure it as a desired capability
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(CapabilityType.PROXY, seleniumProxy); // 默认selenium server起在4444端口,可在capabilities中配置端口
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), capabilities);

同样需去Selenium官网下载standalone-server的jar包,下下来后java -jar xxx.jar 即可运行,相关参数配置见文档。须注意的是,3.x的selenium server需要jdk8支持,2.x只需要jdk1.7支持。

其实如同以上例子,可根据需求自由组合browsermob和selenium的使用。browsermob 2.x的ProxyServer换成了BrowserMobProxyServer,但其实接口大同小异,它的filter概念有点类似之前的interceptor概念,拦截修改了request后返回null就可以了(不需要按照方法声明中的返回值真的构造一个response),官网有filter的例子。

maven依赖:

<dependency>
<groupId>net.lightbody.bmp</groupId>
<artifactId>browsermob-core</artifactId>
<version>${browsermob.version}</version>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.lightbody.bmp</groupId>
<artifactId>browsermob-legacy</artifactId>
<version>${browsermob.version}</version>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium.version}</version>
</dependency>

guava会有冲突,需exclude。selenium版本3.3.0, browsermob 2.1.4 。

修改headers支持

其实以上示例中的addHeaders函数就可以修改headers了,亲测可用。但是需注意,你在浏览器看到的request headers不代表最终的headers,你最好用个 php页面 把server端真正的request打印出来才能看到效果。相关解释。可以自己做个试验证实,比如把Host或者一些重要字段随便填写,去访问baidu等,你会发现访问不了,改回去headers就可以了。

  

Selenium 3 + BrowserMobProxy 2.1.4 模拟浏览器访问 (含趟坑)的更多相关文章

  1. php -- php模拟浏览器访问网址

    目前我所了解到的在php后台中,用php模拟浏览器访问网址的方法有两种: 第一种:模拟GET请求:file_get_contents($url) 通过php内置的 file_get_contents ...

  2. 第14.7节 Python模拟浏览器访问实现http报文体压缩传输

    一. 引言 在<第14.6节 Python模拟浏览器访问网页的实现代码>介绍了使用urllib包的request模块访问网页的方法.但上节特别说明http报文头Accept-Encodin ...

  3. 第14.6节 使用Python urllib.request模拟浏览器访问网页的实现代码

    Python要访问一个网页并读取网页内容非常简单,在利用<第14.5节 利用浏览器获取的http信息构造Python网页访问的http请求头>的方法构建了请求http报文的请求头情况下,使 ...

  4. Java网络编程(模拟浏览器访问Tomcat服务器)

    程序运行结果: HTTP/1.1 404 Not FoundServer: Apache-Coyote/1.1Content-Type: text/html;charset=utf-8Content- ...

  5. HttpWebRequest 模拟浏览器访问网站

    最近抓网页时报错: 要么返回 The remote server returned an error: (442)要么返回: 非法访问,您的行为已被WAF系统记录! 想了想,就当是人家加了抓网页的东西 ...

  6. java 实现模拟浏览器 访问网站

    一般的情况下我们都是使用IE或者Navigator浏览器来访问一个WEB服务器,用来浏览页面查看信息或者提交一些数据等等.所访问的这些页面 有的仅仅是一些普通的页面,有的需要用户登录后方可使用,或者需 ...

  7. 黄聪:wordpress如何携带cookie模拟浏览器访问网站

    $args = array( 'user-agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, li ...

  8. java模拟浏览器包selenium整合了htmlunit,火狐浏览器,IE浏览器,opare浏览器驱

    //如果网页源码中有些内容是js渲染过来的,那你通过HttpClient直接取肯定取不到,但是这些数据一般都是通过异步请求传过来的(一般都是通过ajax的get或者post方式).那么你可以通过火狐浏 ...

  9. python 模拟浏览器

    想用python模拟浏览器访问web的方法测试些东西,有哪几种方法呢? 一类:单纯的访问web,不解析其js,css等. 1. urllib2 #-*- coding:utf-8 -* import ...

随机推荐

  1. [转] mongodb下载、安装、配置与使用

    记得在管理员模式下运行CMD,否则服务将启动失败. 详细图解,记录 win7 64 安装mongo数据库的过程.安装的版本是 MongoDB-win32-x86_64-2008plus-ssl-3.4 ...

  2. Docker Client (another java docker client api)

    前一篇提到了docker-java,这里介绍另一个docker client 库,Docker Client 版本兼容 兼容17.03.1~ce - 17.12.1~ce (点 [here][1]查看 ...

  3. tasksetCPU亲和力&docke容器资源限制

    [taskset详解] taskset设置cpu亲和力,taskset能够将一个或者多个进程绑定到一个或者多个处理器上运行 参数: 选项: -a, --all-tasks 在给定 pid 的所有任务( ...

  4. ELK 环境搭建3-Logstash

    一.Logstash是一款轻量级的日志搜集处理框架,可以方便的把分散的.多样化的日志搜集起来,并进行自定义的处理,然后传输到指定的位置,比如某个服务器或者文件或者中间件. 二.搭建 1.因为要涉及到收 ...

  5. BZOJ2119 股市的预测 字符串 SA ST表

    原文链接https://www.cnblogs.com/zhouzhendong/p/9069171.html 题目传送门 - BZOJ2119 题意 给定一个股票连续$n$个时间点的价位,问有多少段 ...

  6. scrapy 命令行创建 启动 跟踪

    不是python文件中的,而是在虚拟机中运行的命令行,先要workon进入虚拟环境 2.scrapy 框架的使用 -1.新建项目 命令:scrapy startproject <project_ ...

  7. DDoS攻击与防御(2)

    2.攻击系统资源终端设备在与服务器进行通信时,经常需要创建会话连接,在此过程中通常会使用TCP和SSL等协议.会话连接一旦被占满,新进入的会话请求就必须等待前面的会话完成.消耗系统资源的DDoS攻击的 ...

  8. Linux下发送邮件

    Linux下发送邮件 1.配置 vim /etc/mail.rc 文件尾增加以下内容 set from=ymwugui@linuxidc.com smtp=smtp.sina.com.cn set s ...

  9. f5到底刷新了点什么,你知道吗

    引言 前面翻到了http缓存相关内容,关于强制缓存和协商缓存,他们之间的差别可能大家比较清楚. 并且常规情况下是否该使用缓存以及使用哪种缓存, 相关文章多且全,这里不再赘述. 不过用户的不同行为会打破 ...

  10. 双重保险——前端bootstrapValidator验证+后台MVC模型验证

    我们在前端使用BoostrapValidator插件验证最基本的格式要求问题,同时在后台中,使用MVC特有的模型验证来做双重保险.对于boostrapValidator我就不说了,具体请看<bo ...