最近在做项目的时候有一个需求:从网页面抓取数据,要求是首先抓取整个网页的html源码(后期更新要使用到)。刚开始一看这个简单,然后就稀里哗啦的敲起了代码(在这之前使用过Hadoop平台的分布式爬虫框架Nutch,使用起来是很方便,但是最后因为速度的原因放弃了,但生成的统计信息在后来的抓取中使用到了),很快holder.html和finance.html页面成功下载完成,然后解析完holder.html页面之后再解析finance.html,然后很沮丧的发现在这个页面中我需要的数据并没有在html源码中,再去浏览器查看源码果然是这样的,在源码中确实没有我需要的数据,看来不是我程序写错了,接下来让人身心疲惫的事情来了---获取包含动态内容的html页面。

  在所谓的中国最强搜索引擎---百度上面行走了好长的时间,发现大部分的人都在将使用WebDriver和HttpUnit(其实前者已经包含了后者),这个高兴,终于找到了解决办法。怀着万分的激动使用WebDriver,我要想骂人了。

  下面是关于WebDriver的吐槽

  WebDriver是一个测试框架,原本设计的时候就不是用来服务爬虫的,但是我想说的是:八字就差一撇了,你就不能多往前做一步吗?为什么网上还有那么多的人推荐WebDriver呢?我想这些人没有从实际出发,甚至还有的人狂言WebDriver可以解析完成后的页面返回给想要爬去整个页面的人(包含动态生成的内容),对,WebDriver可以完成这个任务,但是看到作者写的代码,我想说的是:哥们,你的代码局限性太大了,解析自己写的js代码,而且js代码简单,这样WebDriver当然是毫无压力的完成任务。WebDriver在解析动态内容是要看js代码的复杂性和多样性。

  什么是复杂性?

    先贴一段代码

WebDriver driver = newInternetExplorerDriver ();HtmlPage page = driver.get(url);System.out.println(page.as

这一段代码的意思是相信大家都看懂,上面使用的IE内核,当然还有FirefoxDriver, ChromeDriver,HtmlUnitDriver,这些driver的使用原理都是一样的,先开启浏览器(这个要时间的),然后加载url并完成动态解析,然后通过page.as

  什么是多样性

  前面说了,浏览器解析js是需要时间的。对于只嵌入少数的js代码的页面来说,通过page.as

  

WebDriver driver = new InternetExplorerDriver();HtmlPage page = dirver.get(url);Thread.sleep(2000);System.output.println(page.as

我按照这个想法去尝试以下,呀,真的是可以。但是问题不正好也摆在那里了么?怎么样去确定等待时间?类似于数据挖掘中确定阀值时的凭经验的方法?,还是尽可能的是时间长一点。我觉得这些都不是很好的办法,时间代价比较大。我就想在driver应该可以捕获解析js完成后的状态,于是我去找啊,找啊,可是根本就没有这个方法,所以我说WebDriver的设计者为什么不再往前走一步,让我们可以在程序中获取到driver解析js完成后的状态,这样的话就不用使用Thread.sleep(2000)这样的不确定性代码了,可惜的是怎么也找不到,真是让我心痛了一场。FirefoxDriver, ChromeDriver,HtmlUnitDriver也有同样的问题,可以说使用WebDriver来辅助爬去动态生成的网页所得到的结果是很不稳定的。这一点我是深有体会,使用IEDriver的时候,同一个页面两次爬取的结果会出现不一样,而且甚至有时候IE直接挂掉,你说这样的东西你们敢用在爬虫程序中吗?我是不敢的。

  另外还有就是有人推荐使用HttpUnit,其实WebDirver中HtmlUnitDriver在内部使用的就是httpUnit,所以使用HttpUnit也会遇到同样的问题,我也做了实验,确实是这样。通过Thread.sleep(2000)来等待js的解析完成,我觉得不可取的办法。不确定性太大了,特别是在大型的抓取工作中。

  总结一下,WebDriver是为测试而设计的框架,虽然按照其原理理论上可以用来辅助爬虫获取包含有动态内容的html页面,但是在实际的应用中是不取的,不确定性太大了,稳定性太差,速度太慢,我们还是让框架各尽其值吧,不要折煞了他们的优点。

  我的工作没有完成,所以继续去网上需找办法,这次找到了一个稳定的,确定性高的辅助工具---phantomjs,目前我还不完全了解这个东西。但是目前已经用它来实现了我想要的功能。在java中通过runtime.exec(arg)来调用phantomjs得到解析js后的页面。我还是把代码贴出来吧

  phantomjs端要执行的代码

system = require('system')  address = system.args[1];//获得命令行第二个参数 接下来会用到  //console.log('Loading a web page');  var page = require('webpage').create();  var url = address;  //console.log(url);  page.open(url, function (status) {    //Page is loaded!    if (status !== 'success') {      console.log('Unable to post!');    } else {    //此处的打印,是将结果一流的形式output到java中,java通过InputStream可以获取该输出内容    console.log(page.content);    }     phantom.exit();  });  

java端执行的代码

  

public void getParseredHtml(){ String url = "www.bai.com"; Runtime runtime = Runtime.getRuntime(); runtime.exec("F:/phantomjs/phantomjs/phantomjs.exe F:/js/parser.js "+url); InputStream in = runtime.getInputStream(); //后面的代码省略,得到了InputStream就好说了   }

这样的话在java端就可以获得解析完成后的html页面了,而不是像WebDriver中需要使用Thread.sleep()这样的不确定性的代码来获取可能完成的代码。有一点需要说明:在phantomjs端的js代码千万不要要语法错误,否则js代码编译不同的话,java端就一直等待着,并不会抛异常。再就是由于在使用phantomjs.exe的时候,java端每次都要去开启一个phantomjs进程,时间上消耗还是比较大的。但是最起码来说结果是稳定的。当然最后我还没有使用phantomjs,我直接download需要的数据,并没有去抓取整个完整的页面,主要是速度方面的问题(其实,我不敢用是因为phantomjs不熟悉,所以我慎用)。

  折腾了几天,虽然没有解决我的问题,但是见识长了不少,后期的工作是熟悉phantomjs,看能不能再速度方面提升,要是能打破速度的框框,以后再爬去网页的时候就得心应手了,再者就是Nutch这个框架,我佩服着哥们在使用的时候方便性,所有后期很有必要研究下如何优化Nutch在Hadoop上的抓取速度,另外,Nutch原始的功能中也不会抓取动态生成的页面内容,但是可以使用Nutch和WebDirver结合,说不定抓取的结果稳定了,哈哈,这些只是构想,但是不尝试怎么知道呢?

  如果对于使用WebDriver辅助爬虫所得到的结果的稳定性方面有要说的,欢迎各位评论啊,因为我确实没有找相关的资料来稳定爬去结果。

怎样用java编程抓取动态生成的网页相关推荐

  1. java抓取动态生成的网页

    最近在做项目的时候有一个需求:从网页面抓取数据,要求是首先抓取整个网页的html源码(后期更新要使用到).刚开始一看这个简单,然后就稀里哗啦的敲起了代码(在这之前使用过Hadoop平台的分布式爬虫框架 ...

  2. java 数据抓取 动态获得cookies里变动的属性_@CookieValue获取Cookie信息,使用Servlet API作为入参,处理模型数据...

    @RequestMapping("/testCookieValue") public String testCookieValue(@CookieValue(value=" ...

  3. 用Java抓取RSS生成Mobi文件发送到Kindle

    最近写了个小工具,通过抓取RSS生成适合Kindle展示的Mobi格式的文件,并发送到Kindle 个人图书馆,也算是继续"自动化"之旅. 代码前前后后写了个把月,趁着放假期间,决 ...

  4. Hawk: 无编程抓取淘女郎的所有高清照片

    1.这是什么鬼? 哦?美女? 最近看了这一篇文章:http://cuiqingcai.com/1001.html 大概说的是用Python和Pyspider(这货好像是我的一位师兄写的,吓尿),抓取淘 ...

  5. Java爬虫抓取豆瓣读书信息

    要求: Java爬虫抓取豆瓣读书信息中关于"编程,算法,互联网"评分最高的前100本书(要求评论数量大于1000) 实现思路: 1.通过手动打开豆瓣读书的主页面 https://b ...

  6. scrapy和selenium结合抓取动态网页

    1.安装python (我用的是2.7版本的) 2.安装scrapy:   详情请参考 http://blog.csdn.net/wukaibo1986/article/details/8167590 ...

  7. python网页数据存入数据库_python网络爬虫抓取动态网页并将数据存入数据库MySQL...

    简述 以下的代码是使用python实现的网络爬虫,抓取动态网页 http://hb.qq.com/baoliao/ .此网页中的最新.精华下面的内容是由JavaScript动态生成的.审查网页元素与网 ...

  8. 手把手视频:万能开源Hawk抓取动态网站

    Hawk是沙漠之鹰历时五年开发的开源免费网页抓取工具(爬虫),无需编程,全部可视化. 自从上次发布Hawk 2.0过了小半年,可是还是有不少朋友通过邮件或者微信的方式询问如何使用.看文档还是不如视频教 ...

  9. python网站数据写入mysql_python网络爬虫抓取动态网页并将数据存入数据库MySQL

    简述 以下的代码是使用python实现的网络爬虫,抓取动态网页 http://hb.qq.com/baoliao/ .此网页中的最新.精华下面的内容是由JavaScript动态生成的.审查网页元素与网 ...

最新文章

  1. 关于页游垂直同步的若干问题
  2. 离职交接文档_如何写好离职工作交接文档?
  3. -f shell 模糊匹配_生产力工具:shell 与 Bash 脚本
  4. 16款新品发布,数据揭秘小米MIX荣归背后逻辑
  5. tensorflow lstm 预测_解析seq2seq原理+tensorflow实现
  6. Sum in the tree
  7. service能去调另外一个service吗_kubernetes的service和pod是如何关联的?
  8. 仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器,适配了iOS6-10系统,3行代码即可集成....
  9. java递归单链表查找中间元素_《数据结构与算法——C语言描述》答案 3.11 查找单链表中的特定元素(递归)...
  10. 吴恩达机器学习 7.神经网络参数的反向传播算法
  11. 第六章 副词(Les adverbes )
  12. python socket 连续send,出现粘包问题
  13. Java foreach
  14. 语言叮叮消息接口_五分钟学后端技术:如何学习Java工程师必知必会的消息队列...
  15. Failure to find com.rongpd:rpd:pom:1.0 in xxx was cached in the local repository, resolution will no
  16. Java迭代器和lambda的区别_【Java公开课|Java 使用Lambda表达式遍历Iterator迭代器,是你学习Java的超车途径】- 环球网校...
  17. rls自适应滤波器matlab实现,Matlab自适应滤波器设计Demo——LMS,RLS
  18. 利用python批量读取图片的EXIF信息并保存为txt文件
  19. Django 修改时区时间
  20. RSA+AES混合加密实例

热门文章

  1. 吃饭困难选择症python_一到吃饭不知道吃啥?美食困难选择症患者是这样解决的...
  2. 程序员永远都不会出轨? 和程序员谈恋爱的真实感受
  3. 移动安全-APK代码混淆
  4. 苏州学生python培训学校
  5. Arduino:交通信号灯
  6. 登录慕测平台从慕测开发者测试练习的Triangle和NextDay程序中分别生成满足100%语句覆盖、函数覆盖
  7. 非程序员的编程之旅——Python基础篇(5)函数
  8. Android 知识点梳理,较完整
  9. druid分布式mysql_Druid 监控分布式解决方案
  10. 登录王者荣耀显示服务器连接错误,王者荣耀登录操作失败怎么回事?请稍后再试解决办法[多图]...