编写爬虫会使用到的一些模块

  • request 模块

    用于简化HTTP请求

  • cheerio 模块

    jquery core 的子集,实现了与DOM操作无关的API

  • async 模块

    用于简化异步代码的编写

  • debug 模块

    用于显示调试信息

  • cron 模块

    用于定时执行任务

  • child_process API

    用于启动新的进程

  • pm2 模块

    用于自动重启程序

  • uncaughException 处理错误

    process.on(‘uncaughtException’, function (err) {

      console.error('uncaughtException: ', err.stack);
    

    })

阅读全文

learnyounode 练习

learnyounode 是 nodeschool.io 出品的nodejs入门练习项目

通过这个练习算是对nodejs有了个入门的认识吧,边学边敲边写笔记

  • 2.输入任意数字求和.js

    // 输入任意个数字,输出这任意个数字的和
    // process.argv 变量保存了输入的参数,注意第一个永远为'node',第二个是执行路径'path/to/my/file',第三个开始才是我们真正传入的参数
    // 传入的参数当做字符串了,注意类型转换,如下面Number() 将数字字符转换为数字再进行计算
    
    var len = process.argv.length;
    // slice(2) 截取数组
    var numbers = process.argv.slice(2);
    var sum = 0;
    for (var i = numbers.length - 1; i >= 0; i--) {
          sum += Number(numbers[i]);
    };
    console.log(sum);
    

阅读全文

express提供的中间件

Express 框架中常用的一些中间件的使用方法

  • basiAuth 访问控制

      // 帐号密码正确时才发回 true,才能继续访问
      var express =  require('express');
      var app = express();
      // 这里的用户名和密码应从数据库读取
      app.use(express.basicAuth('username', 'password'));
      app.get('/', function (req, res) {
          res. send('成功登录后才会看到这段内容。');
      });
      app.listen(1234, 'localhost');
    
  • bodyParse 处理请求 body 的内容

      // 内部使用 JSON    编码、url 编码处理和文件的上传处理
      // 处理一个上传文件
      <body>
        <h1>使用 express.bodyParser 中间件上传文件</h1>
        <form id="myForm" action="upload.html" method="post" enctype="multipart/form-data">
          <input type="file" id="file" name="file">
          <input type="submit" onclick="uploadFile()" value="上传">
        </form>
        <div id="result">
          选择文件后,点击按钮上传.
        </div>
      </body>
    
    // 帐号密码正确时才发回 true,才能继续访问
    var express =  require('express');
    var connect = require('connect');
    var fs = require('fs');
        var app = express();
    // 使用 bodyParser 处理上传
    // app.use(express.bodyParser());
    app.use(connect.urlencoded());
    app.use(connect.json());
    app.get('/upload.html', function (req, res) {
      res.sendFile(__dirname + '/upload.html');
    });
    // 开始处理
    app.post('/upload.html', function (req, res) {
      var file = req.files.myFile;
      // 读取文件
      fs.readFile(file.path, function (err, data) {
        if (err) throw err; //读取文件失败
        fs.writeFile(file.name, data, function (err) {
          if (err) throw err; // 写入文件失败
          res.send('文件上传成功!');
        })
      })
    })
    app.listen(1234, 'localhost');
  • compress 压缩响应流数据

      // 在其他中间前调用才能保证全部数据流都压缩
    
  • cookieParser 处理 cookie

      var express = require('express');
      var app = express();
      // 使用 cookieParser 处理 cookie
      app.use(express.cookieParser());
      // 提前在 cookie.html 中埋下 cookie
      app.get('/cookie.html', function (req, res) {
          res.sendFile(__dirname + '/cookie.html');
      });
      app.post('/cookie.html', function (req, res) {
        var cookies = req.cookies;
        // 开始处理
        for (var key in cookies) {
          res.write('名:', key);
          res.write('值:', cookies[key]);
          res.write('</br>');
        }
        res.end();
      });
      app.listen(1234, 'localhost');        
    
  • csrf 防止跨站访问

      // 与 session 中间件 和 bodyParser 中间件配合使用
    
  • directory 列出某目录下的文件列表

      // app.use(express.directory(path, [options]))
      // 与 express.static 配合使用
      app.use(express.static(__dirname));
      app.use(express.directory(__dirname), {icons: true}); // 显示文件icon
      // 此时会列出文件目录,且点击静态文件(如js/css)可直接访问
    
  • errorHandler 捕获错误

  • limit 限制请求提交数据的字节数

      // 限制为 1M,超出则报错
      var size = 1024*1024; // 1M
      app.use(express.limit(size))
    
  • logger 输出日志到文件中

      // app.use(express.logger([options]))
      // options = {
      //    immediate: false, // 是否在接收到客户端请求时就输出日志,否则服务器端发送完响应数据才输出
      //    format: 'default', // 可选 default/short/tiny/dev,即输出日志的格式        //  stream: process.stdout, // 指定输出数据流的对象
      //     buffer: undefined, // 整数毫秒则指定缓存区有效时间啊暖,或为 true 时,使用缓存区且有效时间为 1000ms
      // }
      var express = require('express');
      var app = express();
      app.use(express.logger({
          format: 'default',
          stream: process.stdout
      }))
    
  • methodOverride 为 bodyParser 提供 HTTP 支持

  • reponseTime 在响应头添加 X-Request-Time 字段

      // 使用后可在 浏览器控制台查看到响应头多了一个 X-Request-Time 
      app.use(express.responseTime());
    
  • router 提供路由功能

      // express 3.x 隐式使用了 router 
    
  • session 提供session功能

      // session 加密过的数据保存在 cookie 中
      app.use(express.session([options]))
      options = {
          key: connect.sid, // 字符串,指定保存这个 session 的 cookie 名
          store: , // 保存 session 的第三方存储对象
          fingerprint: function () {}, // 一个自定义指纹生成函数
          cookie: {path: '/', httpOnly: true, maxAge: 14400000}, // 指定保存 session 的设置 cookie 的对象
          secret: 'xiaolai', // 字符串,用于 session 的数据加密(加盐)
      }
    
      // 使用这个中间件后,就有了 req.session 属性
      var express = require('express');
      var app = express();
      app.use(express.cookieParser());
      app.use(express.session({secret: 'xiaolai'}));
      app.get('/', function (req, res) {
          res.sendFile(__dianema + '/index.html');
          // 开始设置
          req.session.username = 'xiaolai';
          req.session.password = 'password';
    
          // 重新生成
          // req.session.regenerate(function (err) {});
    
          // 销毁
          // req.session.destroy(function (err) {});
      })
    
  • static 设置访问静态文件的功能

      // public 为存放静态文件的目录
      app.use(express.static('public'))
    
  • 自定义错误处理中间件

      app.use(function (err, req, res, next) {
          // 输出错误到服务端
          console.log(err.stack);
          next();
      })    
      app.use(function (err, req, res, next) {
          // 输出错误到客户端
          res.send(500, err.message);
      })    
    

阅读全文

NODEJS-常用模块

dns模块 解析域名

  • dns.resolve() 将一个域名解析为一组DNS记录

  • dns.reverse() 将一个IP地址饥饿虚伪一组域名

  • dns.lookup() 将一个域名转换为一个IP地址

      // rrtype即记录类型,默认为A,可选 A/AAAA/CNAME/MX/TXT/SRV/PTR/NS
      // A 将IPV4地址映射为域名
      // AAAA 将IPV6地址映射为域名
      // CNAME 别名解析,如 laispace.com 是 www.laispace.com 的别名
      // MX 邮件服务器解析
      // dns.resolve(domain, [rrtype], callback)
      var dns = require('dns');
      var domain = 'www.laispace.com';
      dns.resolve(domain, 'A', function (err, addresses) {
          if (err) {
              throw err;
          }
          console.log('域名解析结果为:\n', addresses);
      })
    

阅读全文

使用net模块创建TCP服务器

  • 创建TCP服务器

      var server = net.createServer([options], [connectionListener])
      // 相当于: 
      // var server = net.createServer([options]);
      // server.on('connection', connectionListener);
    

    方法1:

      // 监听端口
      // port 若为0则分配随机端口号
      // host 缺省则监听来自任何ipv4地址的客户端连接
      // backlog 默认为511,设定等待队列中最大的连接数,超过则拒绝
      server.listen(port, [host], [backlog], [callback])
    

    方法2:

      // 监听指定路径
      server.listen(path, [callback])
    

    方法3:

      // 监听socket句柄
      server.listen(handle, [callback])
    

    以上三种方法的 callback 可改写为:

      server.on('listening', function () {
          // callback code here
      })    
    

阅读全文

NODEJS-fs模块操作文件系统

使用 fs模块 对文件/目录进行操作

  • 读取文件内容

      // fs.readFile(filename, [options], callback) 
      // options 中的 flag 默认为 r,表示读取文件
      fs.readFile('test.txt', function (err, data) {
          if(err) throw err;
          console.log('文件内容是:', data);
      })
    
    // fs.readFileSync(filename, [options]) 
    // 同步方式读取
    try {
        var data = fs.readFileSync('test.txt');
        console.log('文件内容是:', data);
    } catch (err) {
        throw err;
    }

阅读全文

NODEJS-Buffer对象

  • 构造一个指定大小的 buffer

      var newBuffer = new Buffer(1024);
      // var len = newBuffer.length;
    
  • 用指定值初始化 buffer 的内容

      // 填充第10字节开始的内容为 1 
      newBuffer.fill(1, 10);
      // 填充第10~20字节的内容为 2 
      newBuffer.fill(2, 10, 20);
    
  • 用数组初始化 buffer 的内容

      // 用数组 [0, 1, 2] 初始化
      var newBuffer = newBuffer([0, 1, 2]) 
    
  • 用字符串初始化 buffer 的内容

      // 用字符串 'xiaolai' 初始化
      var newBuffer = new Buffer('xiaolai');
      // 指定编码, 默认为 utf8,可选 ascii/utf8/utf16le/ucs2/base64/hex 等编码格式
      // var newBuffer = new Buffer('xiaolai', 'utf8');
    

阅读全文

NPM SSL错误的解决

执行 $ npm update 更新模块的时候,报错:

Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE

查资料发现是防火墙的问题,要解决的话,关闭ssl的严格模式,执行:
$ npm config set strict-ssl false 

然后重新执行 $npm update 即可解决

但别忘了这样会降低npm的安全性,所以可以设置回来:
$ npm config set strict-ssl true

MongoDB入门-CRUD简单操作

按着 mongodb官网 教程安装好后,练习一下CRUD(增加、读取、更新、删除)操作。

// 我把数据库保存在了 ~/nosql/mongodb下

第一步-启动mongodb:

$ cd nosql/mongodb/bin

$ sudo ./mongod

这样,mongodb就启动了,接着是创建数据库。进行简单的CRUD。

第二步-启动 mongo shell

$ ./mongo

第三步-创建数据库laispace

// $ help

// 显示已有的数据库

$ show dbs

// 切换数据库,这里用了新的数据库laispace,则自动创建

$ use laispace

// 注意这时候没有插入数据,但实际上已经创建了

第四步-向数据库中添加数据

// db即表示laispace数据库,先建立users文档并插入一个新用户

$ var newUser = { “name”: “赖小赖”, “email”: “example@gmail.com”};

$ db.users.insert(newUser);

// 继续插入

$ var anotherNewUser = { “name”: “小清”, “email”: “123456@gmail.com”};

$ db.users.insert(anotherNewUser);

# 第五步-查找数据

// 查看laispace是否创建

$ show dbs

// 切换到laispace

$ use laispace

// 查看laispace下有哪些文档

$ show collections

// 查看laispace.users下有哪些数据

$ db.users.find(); // 或 $ db.getCollection(‘users’).find();

// 查看其中一个

$ db.users.findOne({“name”: “小清”});

第六步-更新数据

var xiaoqing = {

“name”: “小清”,
“email”: “abcd@laispace.com”,
“password”: “myLatestPassword”
};

$ db.users.update({“name”: “小清”}, xiaoqing);

$ db.users.findOne({“name”: “小清”});

第七步-删除数据

// 看看已有的数据

$ db.users.find();

$ db.users.find({“name”: “小清”});

// 删除 小清

$ db.users.remove({“name”: “小清”});

$ db.users.findOne({“name”: “小清”});

$ db.users.find();

// 删除全部

$ db.users.remove();
$ db.users.find()

第八步-继续学习

$ console.log(“待补充!”);

阅读全文

NODE入门-一些常用的DNS模块

记录一些Modules的简单用法,方便快速查阅。

  • DNS 解析模块

[javascript]
// 解析DNS
var dns = require(‘dns’);
var href = ‘www.laispace.com’;
var type = ‘A’;
// href 待解析的域名字符串, type 表示记录类型的字符串(A-地址解析/CNAME-别名解析/MX-邮件域名解析/SRV-服务记录等);
dns.resolve(href, type, function (err, result) {
if (err) {
throw err;
}
console.log(‘DNS解析结果是:’, result);
})
[/javascript]

解析结果:

除resolve()方法外,还有lookup()、resolve4()、resolve6()。resolveMx() 等其他方法见:DNS模块官方文档

阅读全文