nodejs通过phantomjs实现下载网页


Posted in NodeJs onMay 04, 2015

功能其实很见简单,通过 phantomjs.exe 采集 url 加载的资源,通过子进程的方式,启动nodejs 加载所有的资源,对于css的资源,匹配css内容,下载里面的url资源

当然功能还是很简单的,在响应式设计和异步加载的情况下,还是有很多资源没有能够下载,需要根据实际情况处理下

 首先当然是下载 nodejs 和 phantomjs

下面是 phantomjs.exe 执行的 down.js

var page = require('webpage').create(),
  system = require('system');
var spawn = require("child_process").spawn

if (system.args.length === 1) {
  console.log('Usage: netsniff.js <some URL>');
  phantom.exit(1);
} else {
  var urls = [];
  page.address = system.args[1];
  page.onResourceReceived = function (res) {
    if (res.stage === 'start') {
      urls.push(res.url);
    }
  };
  page.open(page.address, function (status) {
    var har;
    if (status !== 'success') {
      console.log('FAIL to load the address');
      phantom.exit(1);
    } else {
      console.log('down resource ' + urls.length + ' urls.');
      var child = spawn("node", ["--harmony", "downHtml.js", urls.join(',')])
      child.stdout.on("data", function (data) {
       console.log(data);
      })
      child.stderr.on("data", function (data) {
       console.log(data);
      })
      child.on("exit", function (code) {
       phantom.exit();
      })      
    }
  });
}

下面是对应的node运行的 downHtml.js

"use strict";
var fs = require('fs');
var http = require('http');
var path = require('path');
var r_url = require('url');

var dirCache = {};//缓存减少判断
function makedir (pathStr, callback) {
  if (dirCache[pathStr] == 1) {
    callback();
  } else {
    fs.exists(pathStr, function (exists) {
      if (exists == true) {
        dirCache[pathStr] == 1;
        callback();
      } else {
        makedir(path.dirname(pathStr), function () {
          fs.mkdir(pathStr, function () {
            dirCache[pathStr] == 1;
            callback();
          })
        });
      }
    })
  }
};

var reg = /[:,]\s*url\(['"]?.*?(\1)\)/g
var reg2 = /\((['"]?)(.*?)(\1)\)/
var isDownMap = {};
var downImgFromCss = function (URL) {
  http.get(URL, function(res) {
    //console.log(path.resolve(process.cwd(), 'index.min.css'))
    //res.pipe(fs.createWriteStream(path.resolve(process.cwd(), 'index.min.css')));
    var body = "";
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      body += chunk;
    });
    res.on('end', function () {
      var match = body.match(reg);
      for (var i = 0, len = match.length; i < len; i++){
        var m = match[i].match(reg2);
        if (m && m[2]) {
          var url = m[2];
          let imgUrl = r_url.resolve(URL, url);
          if (!isDownMap[imgUrl]) {
            var uo = r_url.parse(imgUrl);
            let filepath = CWD + '/' + uo.hostname + uo.pathname;
            makedir(path.dirname(filepath), function () {
              http.get(imgUrl, function (res) {
                res.pipe(fs.createWriteStream(filepath));
              })
            })
            isDownMap[imgUrl] = 1;
          }
        }
      }
    });
  });
}

var URLS = process.argv[2].split(',');
var CWD = process.cwd();
//下载资源
URLS.forEach(function (URL) {
  var uo = r_url.parse(URL);
  var filepath;
  if (uo.pathname == '/' || uo.pathname == '') {
    filepath = CWD + '/' + uo.hostname + '/index.html';
  } else {
    filepath = CWD + '/' + uo.hostname + uo.pathname;
  }
  makedir(path.dirname(filepath), function () {
    http.get(URL, function (res) {
      if (URL.indexOf('.css') != -1 || (res.headers["content-type"] && res.headers["content-type"].indexOf('text/css')!= -1)) {
        console.log('down images form css file:' + URL + '.');
        downImgFromCss(URL);
      }
      res.pipe(fs.createWriteStream(filepath));
    })
  });
});

down.js downHtml.js 放在同一个文件夹下 通过下列 cmd 运行

D:\phantomjs-2.0.0-windows\bin\phantomjs.exe down.js http://www.youku.com/

以上所述就是本文的全部内容了,希望大家能够喜欢。

NodeJs 相关文章推荐
Nodejs实现多人同时在线移动鼠标的小游戏分享
Dec 06 NodeJs
nodejs中实现阻塞实例
Mar 24 NodeJs
基于html5和nodejs相结合实现websocket即使通讯
Nov 19 NodeJs
nodejs获取微信小程序带参数二维码实现代码
Apr 12 NodeJs
nodejs个人博客开发第七步 后台登陆
Apr 12 NodeJs
Nodejs读取文件时相对路径的正确写法(使用fs模块)
Apr 27 NodeJs
Nodejs中使用captchapng模块生成图片验证码
May 18 NodeJs
nodejs实现超简单生成二维码的方法
Mar 17 NodeJs
Nodejs 和 Electron ubuntu下快速安装过程
May 04 NodeJs
nodejs 使用http进行post或get请求的实例(携带cookie)
Jan 03 NodeJs
Nodejs实现微信分账的示例代码
Jan 19 NodeJs
nodejs处理tcp连接的核心流程
Feb 26 NodeJs
nodejs实现HTTPS发起POST请求
Apr 23 #NodeJs
PHP和NodeJs开发的应用如何共用Session
Apr 16 #NodeJs
Nodejs学习笔记之测试驱动
Apr 16 #NodeJs
Nodejs学习笔记之入门篇
Apr 16 #NodeJs
Windows系统下使用Sublime搭建nodejs环境
Apr 13 #NodeJs
nodejs开发微博实例
Mar 25 #NodeJs
nodejs中实现阻塞实例
Mar 24 #NodeJs
You might like
百事可乐也出咖啡了 双倍咖啡因双倍快乐
2021/03/03 咖啡文化
PHP中遍历stdclass object的实现代码
2011/06/09 PHP
PHP怎么实现网站保存快捷方式方便用户随时浏览
2013/08/15 PHP
php递归获取目录内文件(包含子目录)封装类分享
2013/12/25 PHP
PHP+MySQL删除操作实例
2015/01/21 PHP
Prototype1.5 rc2版指南最后一篇之Position
2007/01/10 Javascript
JavaScript 事件参考手册
2008/12/24 Javascript
javascript 类型判断代码分析
2010/03/28 Javascript
深入理解JavaScript系列(8) S.O.L.I.D五大原则之里氏替换原则LSP
2012/01/15 Javascript
js取模(求余数)隔行变色
2014/05/15 Javascript
jQuery中outerHeight()方法用法实例
2015/01/19 Javascript
jquery插件NProgress.js制作网页加载进度条
2015/06/05 Javascript
Bootstrap图片轮播组件使用实例解析
2016/06/30 Javascript
jQuery 3.0十大新特性
2016/07/06 Javascript
Web性能优化系列 10个提升JavaScript性能的技巧
2016/09/27 Javascript
js+canvas实现动态吃豆人效果
2017/03/22 Javascript
Node.js中环境变量process.env的一些事详解
2017/10/26 Javascript
vue和webpack打包项目相对路径修改的方法
2018/06/15 Javascript
vue实现密码显示与隐藏按钮的自定义组件功能
2019/04/23 Javascript
vue实现下载文件流完整前后端代码
2020/11/17 Vue.js
Python中实现对Timestamp和Datetime及UTC时间之间的转换
2015/04/08 Python
通过数据库对Django进行删除字段和删除模型的操作
2015/07/21 Python
快速实现基于Python的微信聊天机器人示例代码
2017/03/03 Python
Python实现Pig Latin小游戏实例代码
2018/02/02 Python
Python获取一个用户名的组ID过程解析
2019/09/03 Python
Python 批量读取文件中指定字符的实现
2020/03/06 Python
python构造IP报文实例
2020/05/05 Python
python 对一幅灰度图像进行直方图均衡化
2020/10/27 Python
Opencv常见图像格式Data Type及代码实例
2020/11/02 Python
初一科学教学反思
2014/01/27 职场文书
文明生主要事迹
2014/05/25 职场文书
汽车服务工程专业自荐信
2014/09/02 职场文书
清明祭英烈活动总结
2015/05/11 职场文书
小学英语课教学反思
2016/02/15 职场文书
五年级语文教学反思
2016/03/03 职场文书
分享mysql的current_timestamp小坑及解决
2021/11/27 MySQL