从前面的内容中,我们知道开源爬虫框架Norconex基于BrowserMob Proxy实现了对HTTP请求头和响应头的监听器和修改器。本节将详细介绍BrowserMob Proxy这个开源工具。
BrowserMob Proxy是一个基于Java开发的开源代理工具,它可以捕获并操纵浏览器的请求和响应,甚至可以将捕获的数据存储为HAR文件,用于后续的分析和回放。此外,BrowserMob Proxy还可以模拟各种网络条件,如带宽限制、延迟、丢包等,帮助我们检测网页在不良网络条件下的工作状态。
BrowserMob Proxy提供了两种启动方式:嵌入式启动模式(Embedded Mode)和独立启动模式(Standalone Mode)。
首先,我们来看如何通过独立启动模式(Standalone Mode)启动BrowserMob Proxy。
(1)访问页面https://github.com/lightbody/browsermob-proxy/releases,下载最新发布的版本。
(2)执行命令./browsermob-proxy -port 8080,程序启动后,我们会看到如下的日志信息:
[INFO 2024-06-04T16:11:14,133 net.lightbody.bmp.proxy.Main] (main) Starting BrowserMob Proxy version 2.1.4 [INFO 2024-06-04T16:11:14,169 org.eclipse.jetty.util.log] (main) jetty-7.x.y-SNAPSHOT [INFO 2024-06-04T16:11:14,211 org.eclipse.jetty.util.log] (main) started o.e.j.s.ServletContextHandler{/,null} [INFO 2024-06-04T16:11:14,332 org.eclipse.jetty.util.log] (main) Started SelectChannelConnector@0.0.0.0:8080
(3)需要注意的是,browsermob-proxy程序启动之后,并不会自动创建一个真实的代理实例。我们需要通过调用proxy REST API来创建一个代理实例,具体命令如下:
curl -X POST http://localhost:8080/proxy {"port":8081}
有关更多的指令接口,可以查阅相关文档链接:https://github.com/lightbody/browsermob-proxy#rest-api。
(4)编写代码,将Selenium与BrowserMob Proxy结合使用。具体示例代码如下:
System.setProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY, "/path/to/chromedriver"); ChromeOptions options = new ChromeOptions(); options.setHeadless(false); Proxy proxy = new Proxy(); proxy.setHttpProxy("10.1.25.229:8081"); proxy.setSslProxy("10.1.25.229:8081"); options.setProxy(proxy); ChromeDriver webDriver = new ChromeDriver(options); webDriver.get("https://www.baidu.com"); Thread.sleep(10000); webDriver.quit();
因为BrowserMob Proxy是基于Java语言开发的,所以Java爬虫程序中使用BrowserMob Proxy具有天然的优势。在Java爬虫程序中,我们可以直接以嵌入模式(Embedded Mode)来使用BrowserMob Proxy。具体示例代码如下:
// 创建BrowserMobProxy代理服务器 BrowserMobProxy proxy = new BrowserMobProxyServer(); proxy.setTrustAllServers(true); // 启动代理服务实例 proxy.start(8089); // 转换成Selenium代理对象 Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy); ChromeOptions options = new ChromeOptions(); options.addArguments("--ignore-certificate-errors"); options.setProxy(seleniumProxy); System.setProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY, "/path/to/chromedriver"); ChromeDriver chromeDriver = new ChromeDriver(options); chromeDriver.get("https://www.baidu.com"); Thread.sleep(10000); chromeDriver.quit();
接下来,我们介绍一个BrowserMobProxy与Selenium结合使用的真实场景。假设现在有一个需求,希望在通过Selenium WebDriver框架获取到网页内容的同时,还能获取目标网站响应中的HTTP Header值。单纯依赖Selenium WebDriver实现这一需求可能会比较困难,因为Selenium WebDriver并未提供直接从HTTP响应中获取HTTP Header值的API。然而,通过将Selenium WebDriver与BrowserMobProxy结合使用,这一需求可以轻松实现。相关功能的示例代码如下:
BrowserMobProxy proxy = new BrowserMobProxyServer(); proxy.setTrustAllServers(true); proxy.addResponseFilter((response, contents, messageInfo) -> { if(messageInfo.getOriginalUrl().contains("example.com")) { System.out.println(response.headers().get("Content-Type")); } }); // 启动代理服务实例 proxy.start(9090); // 转换成selenium代理对象 Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy); ChromeOptions options = new ChromeOptions(); options.addArguments("--ignore-certificate-errors"); options.setProxy(seleniumProxy); ChromeDriver chromeDriver = new ChromeDriver(options); chromeDriver.get("https://www.example.com"); chromeDriver.quit();