当前位置:   article > 正文

【java爬虫】selenium+browsermob入门实战_browsermob-core

browsermob-core

爬虫领域,selenium几乎是最无所不能的一个框架了,在传统的爬虫无能为力的时候,我们可以使用selenium来请求动态页面获取信息。

当然,只有selenium还是不够的,因为使用selenium我们只能获取页面上展示的数据,但是无法获取Network请求和响应结果,有些网页并不会将从接口接收到的所有数据都展示到页面上,为了捕捉到这些信息,我们就需要引入到browsermob。这两个框架的强强联合,几乎可以解决我们99%的需求。

使用selenium接管已开启的浏览器

一般情况下使用selenium都是重新开一个浏览器,但是这样会产生一些问题,比如有一些网站你需要登录后才能查询到信息,如果每次都重新开一个浏览器的话,我们就需要重复进行登录的操作,这样非常繁琐。为了适应这样的场景,我们可以打开一个浏览器,然后让selenium将浏览器接管,这样浏览器就会保留我们的登录信息,selenium可以很方便地开始工作。

为了能让selenium顺利接管浏览器,我们首先需要指定端口号来打开浏览器。

首先找到 chrome.exe 快捷方式指向的具体地址,然后将这个地址加入到环境变量

 

添加完环境变量后,我们就可以使用某个指定的端口打开一个chrome客户端

 

 接着我们在selenium中使用配置信息启动Chrome就可以接管客户端了

使用selenium爬取百度热搜信息

在selenium接管浏览器后,我们就可以进行响应操作。我们这边简单地爬取一下百度首页的热搜信息来熟悉一下操作。

首先介绍一下本文会用到的jar包。

  1. <dependency>
  2. <!-- fastjson -->
  3. <groupId>com.alibaba</groupId>
  4. <artifactId>fastjson</artifactId>
  5. <version>1.2.47</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>cn.hutool</groupId>
  9. <artifactId>hutool-core</artifactId>
  10. <version>5.6.5</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>net.lightbody.bmp</groupId>
  14. <artifactId>browsermob-core</artifactId>
  15. <version>2.1.5</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>net.lightbody.bmp</groupId>
  19. <artifactId>browsermob-legacy</artifactId>
  20. <version>2.1.5</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.seleniumhq.selenium</groupId>
  24. <artifactId>selenium-java</artifactId>
  25. <version>4.1.1</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>com.google.guava</groupId>
  29. <artifactId>guava</artifactId>
  30. <version>31.0.1-jre</version>
  31. </dependency>

百度热搜是放在一个<ul>标签下的,并且id为hotsearch-content-wrapper,使用这个id可以找到这个元素,然后逐个遍历其中的<li>就能得到首页的6个热搜信息。

不难发现,每个<li>标签里面都有一个<a>标签用来表示url地址,还有一个<span>标签用来表示热搜的标题,我们主要关注这个两个元素对应的信息

 

 这里简单贴一下selenium中findElement的api

  • findElement(By.id())
  • findElement(By.name())
  • findElement(By.className())
  • findElement(By.tagName())
  • findElement(By.linkText())
  • findElement(By.partialLinkText())
  • findElement(By.xpath())
  • findElement(By.cssSelector())

基本上以上的几个方法就可以解决我们的需求了。

代码非常简单

  1. @Override
  2. public void startSelenium() {
  3. log.debug("开启浏览器");
  4. System.setProperty("webdriver.chrome.driver", DRIVER_PATH);
  5. ChromeOptions options = new ChromeOptions();
  6. options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");
  7. WebDriver driver = new ChromeDriver(options);
  8. log.debug("浏览器启动成功");
  9. driver.get("http://www.baidu.com");
  10. log.debug("开始获取热搜信息");
  11. WebElement element = driver.findElement(By.id("hotsearch-content-wrapper"));
  12. List<WebElement> element_lis = element.findElements(By.tagName("li"));
  13. for(WebElement el : element_lis) {
  14. String url = el.findElement(By.tagName("a")).getAttribute("href");
  15. String title = el.findElement(By.className("title-content-title")).getText();
  16. log.info(title + "=>" + url);
  17. }
  18. }

运行一下代码得到如下信息就代表大功告成啦

使用browsermob获取Network数据

大部分网站使用selenium都可以获取数据,但是有一些网站并不会将所有获取的数据都进行展示,或者说,我们直接读取接口返回的数据会更快速的获取数据,我们这里以淘宝联盟举例。

淘宝联盟的url如下,需要进行登录

阿里妈妈https://pub.alimama.com/portal/v2/pages/promo/goods/index.htm进入到页面后,我们可以发现获取数据的接口是 union.pub.entry,我们可以直接从这个接口获取数据,这样就不需要到页面中去找了。

在编码的时候发现了一个问题,就是使用selenium+browsermob的时候没办法对已经打开的浏览器配置代理信息,所以如果使用selenium接管已经打开的浏览器是拿不到Network数据的,所以本文只能退而求其次,让selenium打开新的浏览器,然后进行登录。

browsermob-proxy +selenium使用 - 知乎browsermob-proxy 一个浏览器的代理 在调试浏览器或者爬取数据的时候,需要使用浏览器的开发者模式,尤其是动态网页,在使用selenium的时候,想要知道到底调用了哪些接口 ##安装 pip install browsermob-proxy这里…https://zhuanlan.zhihu.com/p/363008064我们首先需要实例化browsermob的代理,然后将代理添加到selenium的参数中,接着再实例化selenium,打开chrome浏览器。使用browsermob获取网络请求的方法就是设置两个回调函数,一个是请求的回调函数,一个是响应的回调函数。回调函数的意思就是,有请求或者响应信息的时候,就会执行我们回调函数里面编写的代码。

  1. public void startSelenium() {
  2. // 实例化BrowserMob代理
  3. System.setProperty("webdriver.chrome.driver", DRIVER_PATH);
  4. BrowserMobProxy browserMobProxy = new BrowserMobProxyServer();
  5. browserMobProxy.start();
  6. browserMobProxy.enableHarCaptureTypes(CaptureType.REQUEST_CONTENT, CaptureType.RESPONSE_CONTENT);
  7. browserMobProxy.setHarCaptureTypes(CaptureType.RESPONSE_CONTENT);
  8. browserMobProxy.newHar("kk");
  9. Proxy seleniumProxy = ClientUtil.createSeleniumProxy(browserMobProxy);
  10. // 实例化Selenium
  11. ChromeOptions options = new ChromeOptions();
  12. options.setProxy(seleniumProxy);
  13. options.setAcceptInsecureCerts(true);
  14. //options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");
  15. WebDriver driver = new ChromeDriver(options);
  16. // 网络请求回调函数
  17. browserMobProxy.addRequestFilter(new RequestFilter() {
  18. @Override
  19. public HttpResponse filterRequest(HttpRequest httpRequest, HttpMessageContents httpMessageContents, HttpMessageInfo httpMessageInfo) {
  20. // 打印请求信息
  21. // log.info("request=>" + httpMessageInfo.getUrl());
  22. return null;
  23. }
  24. });
  25. // 网络响应回调函数
  26. browserMobProxy.addResponseFilter(new ResponseFilter() {
  27. @Override
  28. public void filterResponse(HttpResponse httpResponse, HttpMessageContents httpMessageContents, HttpMessageInfo httpMessageInfo) {
  29. // 这里获取打印的信息
  30. log.info(httpMessageInfo.getUrl());
  31. if(httpMessageInfo.getUrl().equals("https://pub.alimama.com/openapi/param2/1/gateway.unionpub/union.pub.entry")) {
  32. // 格式化输出
  33. String str = JSONObject.toJSONString(httpMessageContents.getTextContents(), true);
  34. System.out.println(str);
  35. // 将数据写到文件中
  36. try {
  37. FileWriter writer = new FileWriter("output.txt");
  38. writer.write(str);
  39. } catch (IOException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. }
  44. });
  45. // 打开网页
  46. driver.get("https://pub.alimama.com/portal/v2/pages/promo/goods/index.htm?pageNum=2");
  47. }

执行上述代码,打开浏览器并且登录后,我们就可以拿到相应接口的响应信息了,在项目的根目录看到output.txt就代表数据获取成功,可以发现这个接口的响应数据非常大,里面包含的信息非常多。

总结

到这里,本文的主要内容就介绍完了。使用selenium+browsermob可以非常方便地进行网络数据收集,不过我感觉有一个缺点就是运行起来非常慢,在爬下批量数据的情况下可以使用,但是如果要快速爬取大批量数据的话,还是直接用http去请求接口,对于反爬虫机制比较好的接口,可以去研究一下js逆向,selenium相对于直接去请求接口的一大优势就是不用花时间去研究js逆向,直接写代码去获取数据就完事了。

那么本文就到此结束,如果你有什么想和我交流讨论欢迎评论区留言。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/159520
推荐阅读
相关标签
  

闽ICP备14008679号