Selenium3+BrowserMobProxy2.1.4模拟浏览器访问(含趟坑)
背景
是⼀个Web⾃动化测试的组件,可基于WebDriver去控制弹出浏览器去做⼀系列Web点击或⾏为测试(当然也可以去做⼀些邪恶的事。。),减少重复⼈⼯⽹页测试
的开销。相当于⼀层代理,它配合Selenium使⽤可以在Selenium控制浏览器访问之前在代理层拦截做出⼀些记录(har)、修改等。
⼀般来说,直接使⽤Selenium就⾜够了,但是Selenium有个很致命的问题是不⽀持修改request的参数,⽐如很重要的headers。headers其实是⼀些模拟测试时⽤
来模拟不同的访问和测试安全的重要元信息,从⼀些github issues看Selenium开发⽅似乎拒绝考虑加⼊headers修改功能,以⾃动化测试组件不应该让⽤户修改
headers的理由应付⽤户,并让⼤家使⽤BrowserMobProxy去模拟。如果webdriver也是可控的,这完全是可以做到的,可能会需要协调不同浏览器的webdriver开发
者会有点⿇烦;所以也不知道是开发⽅懒,还是和browsermobproxy的开发⽅有什么关系。。⽽弹出浏览器并能提供⾜够的控制功能的框架⽬前暂没见到其他能与
selenium媲美的。(PhantomJS是在服务端提供了个解析,但并不会事实弹出浏览器模仿真正的浏览器⾏为,也就是说⼀些前端涉及⿏标、悬停等事件的脚本并不能
⽀持)
selenium怎么使用介绍⼀下Selenium3.x⾥⼏个概念:
WebDriver:可以理解为连接不同浏览器的驱动程序,⽐如chrome和firefox的webdriver是不同的,如果selenium相关包没有引⼊你的浏览器,就要考虑去寻了。
内置⽀持的浏览器参见。像IE这种需要windows相关组件⽀持可参考官⽹配置步骤。
:其实就是个可视化的测试案例创建管理的组件,⼀般我们⽤selenium可能是写代码,但部分没那么复杂的测试功能可以通过该IDE去配置,也降低了QC的门槛。使
⽤代码去模拟测试的可忽略IDE的存在。
Selenium Server:⼀般只会在远程测试的时候需要。⽐如公司有台测试机,你想要在上⾯测试但⼜不能在上⾯直接开发,你就可以在测试机起SeleniumServer,本
地测试代码通过RemoteWebDriver的形式去连接它。⼤多数情况下本地测试可以忽略这个server的存在。
BrowserMobProxy会提供⼀个ProxyServer⽤于做转发代理拦截,这个server可以是standalone部署⽀持远程,也可以embed进代码中。由于BrowserMob是Java开
发的,因此JVM的可以⽀持真正的embedded,python等⾮JVM系的只能配置其执⾏路径通过⼦进程的⽅式来伪装embedded,这就是项⽬中需要配置
/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 = ateSeleniumProxy(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
<("yahoo");
需留意的是,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' localhost:8080/proxy", 55555));
executeCMD(String.format("curl -X POST -H \"Content-disposition:json/application\" - H \"Content-type:json/application\" -d '%s' localhost:8080/proxy/" + (port1) + "/        // get the Selenium proxy object
String PROXY = "localhost:8080";
Proxy seleniumProxy = ateSeleniumProxy(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);
embedded browsermob + remote selenium server
BrowserMobProxy proxyServer = new BrowserMobProxyServer();
proxyServer.addHeaders(headers);
proxyServer.start(port);
String PROXY = "localhost:" + port;
Proxy seleniumProxy = ateSeleniumProxy(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("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&le.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&le.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就可以了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。