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 相关文章推荐
使用forever管理nodejs应用教程
Jun 03 NodeJs
基于NodeJS的前后端分离的思考与实践(三)轻量级的接口配置建模框架
Sep 26 NodeJs
Nodejs进阶:express+session实现简易登录身份认证
Apr 24 NodeJs
Nodejs之http的表单提交
Jul 07 NodeJs
nodejs前端自动化构建环境的搭建
Jul 26 NodeJs
nodejs基于mssql模块连接sqlserver数据库的简单封装操作示例
Jan 05 NodeJs
nodejs使用http模块发送get与post请求的方法示例
Jan 08 NodeJs
Linux Centos7.2下安装nodejs&amp;npm配置全局路径的教程
May 15 NodeJs
nodejs更新package.json中的dependencies依赖到最新版本的方法
Oct 10 NodeJs
详解NodeJs项目 CentOs linux服务器线上部署
Sep 16 NodeJs
Nodejs文件上传、监听上传进度的代码
Mar 27 NodeJs
在nodejs中创建child process的方法
Jan 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
PHP 清空varnish 缓存的详解(包括指定站点下的)
2013/06/20 PHP
Laravel使用消息队列需要注意的一些问题
2017/12/13 PHP
PHP中的异常处理机制深入讲解
2020/11/10 PHP
JavaScript 节点操作 以及DOMDocument属性和方法
2007/12/06 Javascript
extjs 时间范围选择自动判断的实现代码
2014/06/24 Javascript
Javascript 拖拽的一些简单的应用(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
快速学习JavaScript的6个思维技巧
2015/10/13 Javascript
原生态js,鼠标按下后,经过了那些单元格的简单实例
2016/08/11 Javascript
js友好的时间返回函数
2016/08/24 Javascript
JavaScript SHA1加密算法实现详细代码
2016/10/06 Javascript
js利用appendChild对标签进行排序的实现方法
2016/10/16 Javascript
微信小程序 video详解及简单实例
2017/01/16 Javascript
Node.js之网络通讯模块实现浅析
2017/04/01 Javascript
JavaScript中三个等号和两个等号你了解多少
2017/07/04 Javascript
随机生成10个不重复的0-100的数字(实例讲解)
2017/08/16 Javascript
基于React Native 0.52实现轮播图效果
2020/08/25 Javascript
vue 组件中使用 transition 和 transition-group实现过渡动画
2019/07/09 Javascript
[03:58]2014DOTA2国际邀请赛 龙宝赛后解密DK获胜之道
2014/07/14 DOTA
git使用.gitignore设置不生效或不起作用问题的解决方法
2017/06/01 Python
Python爬虫_城市公交、地铁站点和线路数据采集实例
2018/01/10 Python
Python数据报表之Excel操作模块用法分析
2019/03/11 Python
Python3匿名函数lambda介绍与使用示例
2019/05/18 Python
python实现微信小程序用户登录、模板推送
2019/08/28 Python
python实现在一个画布上画多个子图
2020/01/19 Python
Python字符编码转码之GBK,UTF8互转
2020/02/09 Python
python获取linux系统信息的三种方法
2020/10/14 Python
日本订房网站,预订日本星级酒店/温泉旅馆:Relux(支持中文)
2020/01/03 全球购物
中秋节超市促销方案
2014/01/30 职场文书
集体生日活动方案
2014/08/18 职场文书
人口与计划生育责任书
2015/05/09 职场文书
评奖评优个人先进事迹材料
2015/11/04 职场文书
小学语文继续教育研修日志
2015/11/13 职场文书
nginx前后端同域名配置的方法实现
2021/03/31 Servers
如何用Navicat操作MySQL
2021/05/12 MySQL
Win11开始菜单添加休眠选项
2022/04/19 数码科技
MyBatis在注解上使用动态SQL方式(@select使用if)
2022/07/07 Java/Android