PhantomJs+MutationObserver实现动态页面数据抓取

       IT行业,支撑业务的变化需要优秀的大量的数据,我们需要适应数据的动态变化,拿到这些动态变化的数据,分析,然后提供给自己的项目,支撑公司的业务。最近,就碰到这种,需要获取网页上不断变化的数据,只有在数据发生变化的时候,才取这个变化的值,并将其存放到库中。

       其实PhantomJs,乍看这个名字,还以为是什么Js,其实吧,它就是一个没有页面的浏览器,它跟其他浏览器的最大的区别就在于它没有界面,内核是用WebKit,这是PhantomJs的官网http://phantomjs.org/ 。PhantomJs的中文资料很少,介绍的也很简单,基本上都是官网的示例,说是在的,这些对我一点都没有帮助,不过,人要学会变通,也就只能将这些简单的进行拼装组合,支撑自己复杂的业务。PhantomJs仅仅只是一个浏览器而已,并不能在数据变化的时候主动告诉我,这是变化的数据。所以,这还需要MutationObserver的支持。

       MutationObserver,乍看名字,也许你就能想到他的实现原理是什么,在我看来,就是个观察者模式,当然,JS具体的实现细节,我不知道,我也没查过。其实计算机很多东西都是相通的,从名字看,也许就能看到他的作用或者能大体猜测到他的实现原理上。

安装

       PhantomJs的使用,需要先安装,详细可以参见官网,官网介绍的很详细,就不累述了。我在使用的时候用到了PhantomJs的以下方法。


使用方法简介

       当然是我使用过的方法的一个简介,其他的,还请移步官网。

       page.onConsoleMessage      监听所有的console.log消息

    page.onConsoleMessage = function(msg){
	console.log(msg);				 	
    };
      

      page.onLoadFinished       界面加载完成之后,进行页面动态数据抓取

    page.onLoadFinished = function(status){
 	  console.log('---------start-----------');  
		page.evaluate(getContent,"test");
    };


      page.open    界面打开,我用到了它的两个参数

   page.open(url, function (status) {   
       //Page is loaded!     
       if (status !== 'success') {     
          console.log('can not start');      
       } else {
       }	        
   }); 
   

     page.evaluate()         支持js操作

   page.evaluate(getContent,postUrl);
     getContent为js的方法名,postUrl为该方法需要传递的参数

     

      剩下的就是MutationObserver对动态数据变化的监听了。

    function getContent(url) {
	  console.log("---------start fetch------------"+url+"---");
		var tar = $('#MarketGrid');
		var MutationObserver = window.MutationObserver|| window.WebKitMutationObserver|| window.MozMutationObserver;
		var observer = new MutationObserver(function(mutations) { 
				mutations.forEach(function(mutation) {
			     var text=$(mutation.target).parents(".ipe-Market").find(".ipe-Market_ButtonText").text();
			     console.log(text);
				})
		});
 	observer.observe(tar[0], { 
  	    attributes: true,
 	    childList: true,
  	    characterData: true,
  	    characterDataOldValue: true,
  	    attributeOldValue:true,
  	    subtree: true});
    }	 


完整的Js为:   

system = require('system')     
address = system.args[1];//获得命令行第二个参数 接下来会用到    
var page = require('webpage').create();     
var url = address; 

page.onConsoleMessage = function(msg){
	console.log(msg);				 	
}; 

 page.onLoadFinished = function(status){
 	  console.log('---------start-----------');  
		var postUrl=getUrl();
		page.evaluate(getContent,"test");
 };

page.open(url, function (status) {   
    //Page is loaded!     
    if (status !== 'success') {     
       console.log('can not start');      
    } else {
    }	        
}); 
function getContent(txt) {
	  console.log("---------start fetch------------"+txt+"---");
		var tar = $('#MarketGrid');
		var MutationObserver = window.MutationObserver|| window.WebKitMutationObserver|| window.MozMutationObserver;
		var observer = new MutationObserver(function(mutations) { 
				mutations.forEach(function(mutation) {
			     var text=$(mutation.target).parents(".ipe-Market").find(".ipe-Market_ButtonText").text();
			     console.log(text);
				})
		});
 	observer.observe(tar[0], { 
  	    attributes: true,
 	    childList: true,
  	    characterData: true,
  	    characterDataOldValue: true,
  	    attributeOldValue:true,
  	    subtree: true}
  	    );
 }	 


运行

       我安装的是Windows版本的PhantomJs,运行的时候,需要进入到对应的bin目录下,然后使用命令格式为:phantomjs  xxx.js  http地址  。


问题及解决方案

       说说我在这中间遇到的一些问题吧。

        第一个问题:实时监测动态数据变化

        刚开始,我并不理解PhantomJs是个什么东西,其实我就是不信这就是一个浏览器,它跟其他浏览器的区别就是没有界面,其他浏览器功能,PhantomJs基本上都有,所以在当MutationObserver在其他浏览器产生作用的时候,当和PhantomJs结合的时候,却不能产生相应的效果的时候,我一度怀疑,这个利用这两个东西动态抓取数据的功能不能实现,原因是在 page.evaluate()中执行MutationObserver的时候,这个里面的页面是死页面,数据根本就不会变化。

        老大否定了我,也是后来老大通过他的手段发现,当运行到page.evaluate()时候,这个时候页面还不存在,还没有那些可能会发生变化的html元素。老大就是老大啊,不得不佩服。

       第二个问题:PhantomJs内存飙升,CPU占用高

       这个问题的原因,在于PhantomJs在运行过程中,因为page.evaluate()中的js方法的问题,导致PhantomJs占用内存越来越大,最终在达到1.5G左右,自动关闭退出。解决办法我就不用说了吧,调试js就好了,找到导致原因的那段js就可以了。

      第三个问题:看到数据动态变化了,但是并没有获取到动态变化的数值

      这个问题的原因其实跟第一个问题有点类似,为什么类似呢?因为我遇到的这两个问题,都跟具体的http请求页面有关,这个问题的出现,是因为里面的html元素的原因,在检测到变化后,并没有拿到值,这个问题隐藏的很深,如果不细致观察很难发现。

       第四个问题:因为PhantomJs启动后,是一个进程,那检测到的数据变化值如何传入到项目中

       解决办法类似的有两个,第一:Ajax请求到项目服务;第二:长期挂起线程,并保持一个活跃状态,或者使用main函数。

       第五个问题:管理问题

       当前,这还涉及到另外的一些问题,如果利用不使用其他额外的工具封装类的话,将面临启动一个数据抓取服务,将启动一个PhantomJs的进程,启动10个的话,将启动10个PhantomJs进程,什么时候启动,什么时候删除PhantomJs的进程,这些都是问题。一个进程大约占用内存50m,如果是10个,就是500m,但是,你能手动去启动,手动去删除吗?显然这是不合理的,至于如何解决,以后告知。


总结

       利用PhantomJs和MutationObserver实现动态网页数据抓取工作,光是调通这个PhantomJs和MutationObserver,用了差不多一周的时间,不断的改造,当然这不是最终版本,其实最终版本比这稍微复杂。PhantomJs的作用还有很多,在数据抓取这个行业中,我想,PhantomJs以后会大有前途的。其实,PhantomJs也有对应的封装工具—PhantomJsDriver,只是我查了下这个封装工具类的API,并没有适合我们这种特殊需求的,所以也就没有深入研究,PhantomJsDriver的中文资料貌似也很少。

       今天老大还跟我说,为什么叫“饭桶”呢?我默默的笑了,也许它在运行上的确很饭桶吧,哈哈。。。。。

       在正式步入工作这个环境,进入互联网这个行业,特别是在最近的一年,我深刻体会到,如果不留心思考,不尝试阅读英文资料,对英文深深抵触,那我就别想在这个行业继续混下去了。处处留心,学着怎么去做一个人,我常常对自己说的话就是,不管在工作还是在生活中,静下心来,身为一个女生,更要理智多于感性,看看自己能够成为一个什么样的人。




 



       

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Selenium是一个用于自动化浏览器操作的工具,而PhantomJS是一个无界面的浏览器。它们可以结合使用来进行爬虫操作。使用Selenium和PhantomJS,你可以模拟用户在浏览器中的操作,例如点击、填写表单等。这样就可以实现爬取网页数据的功能。 安装Selenium和PhantomJS的步骤如下: 1. 首先确保你已经安装了Python 3.5以及pip。 2. 使用pip安装Selenium,运行以下命令: ``` pip install selenium ``` 3. 下载PhantomJS并解压到Python的Scripts目录中。具体下载链接请参考中提供的系统环境下载说明。 安装完成后,你就可以开始使用Selenium和PhantomJS实现爬虫功能了。你可以参考中提供的示例代码来学习如何使用Selenium和PhantomJS进行网页爬取。 此外,关于使用Selenium和PhantomJS进行数据爬取的方法,你可以按照以下步骤进行: 1. 使用Selenium和PhantomJS打开目标网页,模拟用户在浏览器中的操作来获取数据。 2. 如果网页使用了ajax接口来加载数据,你可以通过分析网页源代码或使用开发者工具来找到数据来源的接口,并发送请求获取数据。 3. 如果你只需要获取列表页的数据,可以在第一次爬取时只爬取列表页,将详情页的URL放到每条数据中心。这样可以避免增加请求数量。 4. 如果需要获取详情页的数据,可以在第二次爬取时从数据库中提取详情页URL,并使用Selenium和PhantomJS来爬取详情页的数据。 希望这些信息能对你有所帮助。如果你有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值