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极简入门教程(一):模块机制
Oct 25 NodeJs
nodejs实现的一个简单聊天室功能分享
Dec 06 NodeJs
用NodeJS实现批量查询地理位置的经纬度接口
Aug 16 NodeJs
详解nodejs 文本操作模块-fs模块(二)
Dec 22 NodeJs
NodeJS实现微信公众号关注后自动回复功能
May 31 NodeJs
详解nodejs 配置文件处理方案
Jan 02 NodeJs
NodeJS模块与ES6模块系统语法及注意点详解
Jan 04 NodeJs
NodeJs之word文件生成与解析的实现代码
Apr 01 NodeJs
nodejs通过钉钉群机器人推送消息的实现代码
May 05 NodeJs
nodejs实现聊天机器人功能
Sep 19 NodeJs
nodejs如何在package.json中设置多条启动命令
Mar 16 NodeJs
Nodejs文件上传、监听上传进度的代码
Mar 27 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
我常用的几个类
2006/10/09 PHP
Notice: Undefined index: page in E:\PHP\test.php on line 14
2010/11/02 PHP
php 不使用js实现页面跳转
2014/02/11 PHP
如何让thinkphp在模型中自动完成session赋值小教程
2014/09/05 PHP
php+redis实现商城秒杀功能
2020/11/19 PHP
JavaScript 新手24条实用建议[TUTS+]
2009/06/21 Javascript
MooTools 1.2中的Drag.Move来实现拖放
2009/09/15 Javascript
ExtJs 表单提交登陆实现代码
2010/08/19 Javascript
js 表单提交后按钮变灰的实例代码
2013/08/16 Javascript
Highcharts使用简例及异步动态读取数据
2015/12/30 Javascript
JavaScript学习小结之使用canvas画“哆啦A梦”时钟
2016/07/24 Javascript
微信小程序去哪里找 小程序到底如何使用(附小程序名单)
2017/01/09 Javascript
js实现随机数小游戏
2019/06/28 Javascript
JS中async/await实现异步调用的方法
2019/08/28 Javascript
详解javascript中var与ES6规范中let、const区别与用法
2020/01/11 Javascript
vue实现移动端input上传视频、音频
2020/08/18 Javascript
[02:42]决战东方!DOTA2亚洲邀请赛重启荣耀之争
2017/03/17 DOTA
python WindowsError的错误代码详解
2017/07/23 Python
python正则表达式及使用正则表达式的例子
2018/01/22 Python
解决python删除文件的权限错误问题
2018/04/24 Python
对python:threading.Thread类的使用方法详解
2019/01/31 Python
值得收藏的10道python 面试题
2019/04/15 Python
python Django编写接口并用Jmeter测试的方法
2019/07/31 Python
使用Python+Appuim 清理微信的方法
2021/01/26 Python
CSS3毛玻璃效果(blur)有白边问题的解决方法
2016/11/15 HTML / CSS
HTML5 canvas 瀑布流文字效果的示例代码
2018/01/31 HTML / CSS
伦敦哈德森鞋:Hudson Shoes
2018/02/06 全球购物
婴儿地球:Baby Earth
2018/12/25 全球购物
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
大学教师年终总结的自我评价
2013/10/29 职场文书
积极分子思想汇报
2014/01/04 职场文书
房地产端午节活动方案
2014/08/24 职场文书
上课说话检讨书
2015/01/27 职场文书
农业项目投资意向书
2015/05/09 职场文书
听证会主持词
2015/07/03 职场文书
浅谈MySQL之浅入深出页原理
2021/06/23 MySQL