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 的 session 简单使用
Jun 06 NodeJs
详解Nodejs基于mongoose模块的增删改查的操作
Dec 21 NodeJs
NodeJS基础API搭建服务器详细过程记录
Apr 01 NodeJs
详解Windows下安装Nodejs步骤
May 18 NodeJs
nodejs mysql 实现分页的方法
Jun 06 NodeJs
nodejs读取本地中文json文件出现乱码解决方法
Oct 10 NodeJs
nodejs基础之多进程实例详解
Dec 27 NodeJs
详解nodejs http请求相关总结
Mar 31 NodeJs
nodejs提示:cross-device link not permitted, rename错误的解决方法
Jun 10 NodeJs
浅谈使用nodejs搭建web服务器的过程
Jul 20 NodeJs
NodeJS开发人员常见五个错误理解
Oct 14 NodeJs
nodejs中内置模块fs,path常见的用法说明
Nov 07 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
使用Apache的rewrite技术
2006/06/22 PHP
使用adodb lite解决问题
2006/12/31 PHP
for循环连续求和、九九乘法表代码
2012/02/20 PHP
PHP文件上传类实例详解
2016/04/08 PHP
Javascript代码在页面加载时的执行顺序介绍
2013/05/03 Javascript
javascript+html5实现绘制圆环的方法
2015/07/28 Javascript
jQuery实现两款有动画功能的导航菜单代码
2015/09/16 Javascript
JavaScript获取浏览器信息的方法
2015/11/20 Javascript
JavaScript6 let 新语法优势介绍
2016/07/15 Javascript
JS版微信6.0分享接口用法分析
2016/10/13 Javascript
AngularJS实现表单验证功能
2017/01/09 Javascript
学习JS中的DOM节点以及操作
2018/04/30 Javascript
vue中利用Promise封装jsonp并调取数据
2019/06/18 Javascript
layui prompt 设置允许空白提交的方法
2019/09/24 Javascript
Vue简单实现原理详解
2020/05/07 Javascript
vue-cli3项目配置eslint代码规范的完整步骤
2020/09/10 Javascript
[07:52]2014DOTA2 TI逗比武士游V社解说背后的故事
2014/07/10 DOTA
在Linux下调试Python代码的各种方法
2015/04/17 Python
python列出目录下指定文件与子目录的方法
2015/07/03 Python
Django中使用celery完成异步任务的示例代码
2018/01/23 Python
Python的numpy库中将矩阵转换为列表等函数的方法
2018/04/04 Python
详解python实现识别手写MNIST数字集的程序
2018/08/03 Python
Python tkinter常用操作代码实例
2020/01/03 Python
解决Python pip 自动更新升级失败的问题
2020/02/21 Python
解决python父线程关闭后子线程不关闭问题
2020/04/25 Python
深入解读CSS3中transform变换模型的渲染
2016/05/27 HTML / CSS
印尼值得信赖的在线交易网站:Bukalapak
2019/03/11 全球购物
财务会计人员求职的自我评价
2014/01/13 职场文书
《桃林那间小木屋》教学反思
2014/05/01 职场文书
物理课外活动总结
2014/08/27 职场文书
民事诉讼代理委托书
2014/10/08 职场文书
领导个人查摆剖析材料
2014/10/29 职场文书
2014年材料员工作总结
2014/11/19 职场文书
《语言的突破》读后感3篇
2019/12/12 职场文书
动画电影《擅长捉弄人的高木同学》6月10日上映!
2022/03/20 日漫
vue实现省市区联动 element-china-area-data插件
2022/04/22 Vue.js