PhantomJS采集ajax加载页面数据,采集微信网页

今天采集一个网站,不过它是使用微信授权登陆后才能访问,并且做了验证只能在微信中打开。

用浏览器通过各种手段模拟微信登陆网站后,发现所有的内容都是通过ajax加载的,之前有写过有的验证可以用php的v8扩展做,但是这个不行,我就使用了PhantomJS来采集。

PhantomJS自己去官网下载:http://phantomjs.org/

下载后将目录中的bin目录添加进环境变量中,运行测试 phantomjs test.js

这里有一点要注意,我当时打开官方文档后看到设置cookie的函数格式就晃了一眼,直接复制过来了把多的删除掉,直接就将php设置cookie的思路套上去,没仔细看,直接设置发现没对,仔细看了一下,phantom.addCookie(obj)这个方法是添加一个cookie,包括cookie的作用域,过期时间等,其中name是对应的cookie名称,value对应的是cookie值,如果有多个cookie要添加多次。

还有一点要注意就是,page.open的回调函数是页面框架加载完就会执行,它不会去判断ajax请求是否完成,我测试的时候就直接写的是延迟10秒再读取,并且将页面保存成page.jpg图片,测试通过。

再说两个解决ajax加载延迟的方法。

第一个方法:phantomjs自身的两个事件page.onResourceRequested与page.onResourceReceived,前面一个是请求,后面一个是响应,通过计算请求与响应的数量是否相等来确定ajax是否加载完成,但是这个也不准确,因为有时候响应完了,有些请求还没有发出。

第二个方法:就是判断页面中的某个或某些节点是否出现,如果出现就完成自己的业务逻辑,没有就等待,等到节点出现,或者超时。

两个办法自己选一个吧,异步请求本来就很恶心。

还要注意一个就是超时事件page.onResourceTimeout这个事件超时会触发,这个事件需要设置,page.settings.resourceTimeout要在settings对像中设置它,如果不设置的话是不会触发的。

当然可能有些网站还有反爬虫机制,这个就需要自己去绕过了,并且有些反爬虫他会检测window对像上有没有挂phantom,就是防止用phantom框架来采集,这个可以通过替换的方式干掉它。

下面是我写的测试代码,整个流程能走通,确定有用后记录下流程:

//test.js
var page = require('webpage').create();
var fs = require('fs');
//可以将采集的数据写入到文件中,或者存在sql语句
phantom.addCookie({
		'name'     : 'signDate',   /* required property */
	  'value'    : '2019-1-8',  /* required property */
	  'domain'   : 'xxx',
	  'path'     : '/home',                /* required property */
	  'httponly' : false,
	  'secure'   : false,
	  'expires'  : "2019-01-08T03:13:35.000Z"//(new Date()).getTime() + (1000 * 60 * 60*5)   /* <-- expires in 1 hour */
	});
phantom.addCookie({
		'name'     : 'SessionId',   /* required property */
	  'value'    : '4yffkdso2qptqexj5hhgbhov',  /* required property */
	  'domain'   : 'xxx.com',
	  'path'     : '/',                /* required property */
	  'httponly' : false,
	  'secure'   : false,
	  //'expires'  : "2019-01-08T03:13:35.000Z"//(new Date()).getTime() + (1000 * 60 * 60*5)   /* <-- expires in 1 hour */
	});
page.settings.userAgent = "Mozilla/5.0 (Linux; Android 8.0; ...MicroMessenger/7.0.1380(0x27000038) Process/tools NetType/WIFI Language/zh_CN";

page.onConsoleMessage = function(msg) {
  console.log( msg);
};
var url = "http://xxx.com/Home/Detail?novelId=285&novelTitleNo=3";
page.open(url, function(status) {
	setTimeout(function(){ 
	page.render('page.jpeg', {format: 'jpeg', quality: '100'});
	console.log(status);
	console.log( document.title);
	  phantom.exit();
	}, 10000);
	/*
//有js需要执行的时候使用evaluate函数
  var st = page.evaluate(function() {
    return document.title;
  });
console.log(st);
  */
});

当然可以配合nodejs来完成数据持久化处理,我也准备用nodejs来搞这个采集。感兴趣的就自己研一下吧。



Tags javascript 建站

留言(0)

评论