Java网络爬虫(十四)--PhantomJs的使用及性能优化
来源:互联网 发布:初中生编程比赛语言 编辑:程序博客网 时间:2024/06/15 10:00
先说点题外话吧,在我刚开始学习爬虫的时候,有一次一个学长给了我一个需求,让我把京东图书的相关信息抓取下来。恩,因为真的是刚开始学习爬虫,并且是用豆瓣练得手,抓取了大概500篇左右的影评吧,然后存放到了mysql中,当时觉得自己厉害的不行,于是轻松的接下了这个需求。。。
然后信心满满的开始干活。。首先查看网页源代码。。。???我需要的东西源代码里面没有!!!然后去问了学长。学长给我说,这是AJAX产生的数据,大概听完之后我就去查了资料。发现网上大片的资料都在阐述一个道理,对于动态页面,使用PhantomJs进行抓取,但是这样效率很低。作为一个优秀的程序员,当时看见效率很低这四个字,那在我心里是绝对不能被允许的,所以我就采用了抓包的方式,查看AJAX数据所在的URL,对于这个模拟浏览器的方法也就一直搁置到现在。
但是既然知道了这个东西,哪有不去学习的道理。所以我抽出了一点时间看了一下关于Java方面使用PhantomJs的资料,现在分享给大家。
对了,其实做网络爬虫,页面上90%的数据都可以使用抓包进行获取。所以我还是鼓励大家直接请求自己所需数据所在的URL。毕竟这种方式虽然方便,但是效率低下。
JS渲染与AJAX
在学习这个东西之前我们首先得了解什么是JS渲染、什么是AJAX以及为何这两种数据我们在网页源码里面获取不到。
依照我的理解,JS渲染与AJAX是一种相辅相成的关系,AJAX负责异步从服务器端获取数据,拿到数据后再使用JS进行渲染,最后呈现给用户。由于在Java中,HttpClient只能请求简单的静态页面,并不能请求到页面完全加载好后由JS调用相关代码产生的异步数据,所以我们不能直接通过HttpClient获取AJAX与JS渲染产生的数据。此时按上面所说的推荐大家直接进行网络抓包拿到AJAX数据所在的URL,或者使用本文所说的PhantomJs渲染引擎。
三大JS渲染引擎的比较
在网上进行资料查阅的时候,我们经常会因为五花八门的答案而不知所措,这时候一是要保持一颗平静的心情,二就要考虑搜索问题的相关姿势,必要的时候还需要科学上网。
先不说本文所说的JS渲染引擎,单说在Java爬虫中HTTP请求的库简直就可以用五花八门来形容,Java的原生HttpURLConnection类,HttpClient第三方库等等… …当然网络上提供了这么多方法,我们必须要进行选择,那么我们肯定想选择功能强大的,使用简单的类库。此时我们就应该在网上搜索对两个类库做相关比较的问题,来进行更好的选择,而不是随便挑一个学习就完事了,这样很有可能投入的学习成本与回报不成正比。
那么相信大家在准备使用JS引擎模拟浏览器的时候,在网上看过不仅有PhantomJs,还听说过Selenium,HtmlUnit这两个具有相同功能的东西。那么我们该如何选择呢?下图截选自其他网友的博客:
这也是我选择讲述PhantomJs的原因。
网上PhantomJs和Selenium还经常成对出现,原因是Selenium封装了PhantomJs的一部分功能,Selenium又提供了Python的接口模块,在Python语言中可以很好地去使用Selenium,间接地就可以使用PhantomJs。然而,是时候抛弃Selenium+PhantomJs了,原因之一此封装的接口很久没有更新了(没人维护了),原因之二Selenium只实现了一部分PhantomJs功能,且很不完善。
PhantomJs的使用
我使用的Ubuntu16.04的开发环境,至于PhantomJs + Selenium的环境部署,网络上有大篇资料,我就在这里给大家引入一个链接,也不详细说明了:ubuntu安装phantomjs
关于PhantomJs和Selenium的介绍我也就不再详说,大家直接百度就可以了。我们直接来看一下在Java中应该怎么使用PhantomJs~
如果你没有使用Maven的话,就在网上下载第三方jar包。我们所需要的Maven依赖如下:
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java --><dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.53.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.github.detro.ghostdriver/phantomjsdriver --> <dependency> <groupId>com.github.detro.ghostdriver</groupId> <artifactId>phantomjsdriver</artifactId> <version>1.1.0</version> </dependency>
接下来我们来看一下程序到底应该怎么写:
1.设置请求头
//设置必要参数DesiredCapabilities dcaps = new DesiredCapabilities();//ssl证书支持dcaps.setCapability("acceptSslCerts", true);//截屏支持dcaps.setCapability("takesScreenshot", true);//css搜索支持dcaps.setCapability("cssSelectorsEnabled", true);//js支持dcaps.setJavascriptEnabled(true);//驱动支持(第二参数表明的是你的phantomjs引擎所在的路径,使用whereis phantomjs可以查看)dcaps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, "/usr/local/bin/phantomjs");
2.创建phantomjs浏览器对象
//创建无界面浏览器对象PhantomJSDriver driver = new PhantomJSDriver(dcaps);
3.设置隐性等待
//设置隐性等待driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
因为Load页面需要一段时间,如果页面还没加载完就查找元素,必然是查找不到的。最好的方式,就是设置一个默认等待时间,在查找页面元素的时候如果找不到就等待一段时间再找,直到超时。
以上三点是使用PhantomJs时需要注意的地方,大家可以看一下大致的整体程序:
import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.phantomjs.PhantomJSDriver;import org.openqa.selenium.phantomjs.PhantomJSDriverService;import org.openqa.selenium.remote.DesiredCapabilities;import java.util.concurrent.TimeUnit;/** * Created by hg_yi on 17-10-11. */public class phantomjs { public static void main(String[] args) { //设置必要参数 DesiredCapabilities dcaps = new DesiredCapabilities(); //ssl证书支持 dcaps.setCapability("acceptSslCerts", true); //截屏支持 dcaps.setCapability("takesScreenshot", true); //css搜索支持 dcaps.setCapability("cssSelectorsEnabled", true); //js支持 dcaps.setJavascriptEnabled(true); //驱动支持(第二参数表明的是你的phantomjs引擎所在的路径) dcaps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, "/usr/bin/phantomjs-2.1.1-linux-x86_64/bin/phantomjs"); //创建无界面浏览器对象 PhantomJSDriver driver = new PhantomJSDriver(dcaps); //设置隐性等待(作用于全局) driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS); //打开页面 driver.get("--------------------------------"); //查找元素 WebElement element = driver.findElement(By.id("img_valiCode")); System.out.println(element.getAttribute("src")); }}
我成功的抓取到了网页源码里面没有的数据~
关于上面使用到的PhantomJSDriver类的相关API,大家直接看这篇资料即可,应该可以满足你的日常需求了:webdriver API中文版(WebDriver的API同样适用于PhantomJSDriver)。
PhantomJs的性能优化
我们都知道使用PhantomJs这种无头浏览器进行网页源码的抓取是非常费时的,所以当我们决定使用这个工具并且对抓取速度还有一定要求的时候,就需要掌握对PhantomJs进行性能优化的能力。
1.设置参数
Google,Baidu半天,还看了一点官方文档,还是找不到PhantomJs相关的Java调用API文档,好吧,先扔一篇Python的,以后找到这方面的内容再进行补充吧~~~
【phantomjs系列】Selenium+Phantomjs性能优化
题外话:其实对于Java网络爬虫。。。真想吐槽,建议刚开始准备学爬虫的人还是转战Python爬虫吧~~对于Java爬虫,只说一句话:学习难度大,学习周期长,投出与收入不成正比!!!
- Java网络爬虫(十四)--PhantomJs的使用及性能优化
- 使用PhantomJS实现模拟登陆(Java爬虫)
- Java爬虫进阶-Selenium+PhantomJs的运用
- Java爬虫进阶-Selenium+PhantomJs的运用
- Java网络爬虫(十一)--使用多线程全面提升爬虫性能
- Java之网络爬虫WebCollector+selenium+phantomjs(一)
- Java之网络爬虫WebCollector+selenium+phantomjs(二)
- Java之网络爬虫WebCollector+selenium+phantomjs(三)
- Java之网络爬虫WebCollector+selenium+phantomjs(一)
- Java之网络爬虫WebCollector+selenium+phantomjs(二)
- Java之网络爬虫WebCollector+selenium+phantomjs(三)
- oracle 性能优化操作十四: 使用基于函数的索引
- oracle 性能优化操作十四: 使用基于函数的索引
- 系统间通信方式之(ActiveMQ的使用性能优化3)(十四)
- 【网络爬虫】【java】微博爬虫(二):如何抓取HTML页面及HttpClient使用
- pyspider 爬虫教程(三):使用 PhantomJS 渲染带 JS 的页面
- Java网络爬虫(一)--HttpClient的使用
- 优化网站性能的十四条原则
- 点云参考软件pcc的帧内编码函数解析
- java面试编程题(字符相关)
- std::vector::clear
- 10月10日 c语言 输入星星图形3
- 扩展欧几里得算法
- Java网络爬虫(十四)--PhantomJs的使用及性能优化
- 如何使用 Intelij Idea + Maven 实现区分环境并快速编译生成不同环境 war 包
- spring框架-第六弹
- unity_NGUI系统学习(十二)_Checkbox单选框的创建
- 静态链表实现
- leetcode_java_第一题 two sum
- Flask项目文件目录
- C++处理XML文件
- 惊喜!Mat研究(1)