Java 爬虫赶上数据异步加载

  如今不少都是先后端分离项目,这会使得数据异步加载问题更加突出,因此你在爬虫时遇到这类问题没必要惊讶,没必要慌张。对于这类问题的解决办法整体来讲有如下两种:web

  一、内置一个浏览器内核正则表达式

  内置浏览器就是在抓取的程序中,启动一个浏览器内核,使咱们获取到 js 渲染后的页面,这样咱们就跟采集静态页面同样了。这种工具经常使用的有如下三种:chrome

  Seleniumnpm

  HtmlUnitjson

  PhantomJs后端

  这些工具都能帮助咱们解决数据异步加载的问题,可是他们都存在缺陷,那就是效率不高并且不稳定。浏览器

  二、反向解析法前后端分离

  什么是反向解析法呢?咱们 js 渲染页面的数据是经过 Ajax 的方式从后端获取的,咱们只须要找到对应的 Ajax 请求链接就 OK,这样咱们就获取到了咱们须要的数据,反向解析法的好处就是这种方式获取的数据都是 json 格式的数据,解析起来也比较方便,另外一个好处就是相对页面来讲,接口的变化几率更小。一样它有两个不足之处,一个是在 Ajax 时你须要有耐心有技巧,由于你须要在一大推请求中找到你想要的,另外一个不足的地方就是对 JavaScript 渲染的页面一筹莫展。异步

  上面就是异步数据加载的两种解决办法,为了加深你们的理解和在项目中如何使用,我以采集网易要闻为例,网易新闻地址:https://news.163.com/ 。利用上诉的两种方式来获取网易要闻的新闻列表。网易要闻以下:工具

  


  内置浏览器 Selenium 方式

  Selenium 是一个模拟浏览器,进行自动化测试的工具,它提供一组 API 能够与真实的浏览器内核交互。在自动化测试上使用的比较多,爬虫时解决异步加载也常用它,咱们要在项目中使用 Selenium ,须要作两件事:

  二、下载对应的 driver,例如我下载的 chromedriver,下载地址为:https://npm.taobao.org/mirrors/chromedriver/,下载后,须要将 driver 的位置写到 Java 的环境变量里,例如我直接放在项目下,因此个人代码为:

  System.getProperties().setProperty(webdriver.chrome.driver, chromedriver.exe);

  完成上面两步以后,咱们就能够来编写使用 Selenium 采集网易要闻啦。具体代码以下:

  运行该方法,获得结果以下:

  

  咱们使用 Selenium 已经正确的提取到了网易要闻的列表新闻。

  反向解析法

  反向解析法就是获取到 Ajax 异步获取数据的连接,直接获取到新闻数据。若是没有技巧的话,查找 Ajax 的过程将很是痛苦,由于一个页面加载的连接太多了,看看网易要闻的 network:

  


  有几百条的请求,该如何查找到是哪条请求获取的要闻数据呢?你不嫌麻烦的话,能够一个一个的去点,确定可以查找到的,另外一种快捷的办法是利用 network 的搜索功能,若是你不知道搜索按钮,我在上图已经圈出来啦,咱们在要闻中随便复制一个新闻标题,而后检索一下,就能够获取到结果,以下图所示:

  


  这样咱们就快速的获取到了要闻数据的请求连接,连接为:https://temp.163.com/special/00804KVA/cm_yaowen.js?callback=data_callback,访问该连接,查看该连接返回的数据,以下图所示:

  


  从数据咱们能够看出,咱们须要的数据都在这里啦,因此咱们只须要解析这段数据接能够啦,要从这段数据中解析出新闻标题和新闻连接,有两种方式,一种是正则表达式,另外一种是将该数据转成 json 或者 list。这里我选择第二种方式,利用 fastjson 将返回的数据转换成 JSONArray 。因此咱们是要引入 fastjson ,在 pom.xml 中引入 fastjson 依赖:

  除了引入 fastjson 依赖外,咱们在转换前还须要对数据进行简单的处理,由于如今的数据并不符合 list 的格式,咱们须要去掉 data_callback( 和最后面的 )。具体反向解析获取网易要闻的代码以下:

  编写 main 方法,执行上面的方法,须要注意的地方是:这时候传入的连接为https://temp.163.com/special/00804KVA/cm_yaowen.js?callback=data_callback 而不是 https://news.163.com/。获得以下结果:

  


  两种方法都成功的获取到了网易要闻异步加载的新闻列表,对于这两种方法的选取,我我的的倾向是使用反向解析法,由于它的性能和稳定是都要比内置浏览器内核靠谱,可是对于一些使用 JavaScript 片断渲染的页面,内置浏览器又更加靠谱。因此根据具体状况选择吧。

相关文章
相关标签/搜索