NodeJS概述2-事件插件-简易爬虫

事件 events 模块

原生事件写法

  /* 
    * 1. 事件分类
      * DOM0级 事件  - on + eventType
      * DOM2级 事件  - 事件监听
    * 2. 事件构成部分有哪些?    dom.onclick = function () {}
      * 事件源
      * 事件类型  click change ... 
      * 事件处理程序
    * 3. 事件绑定形式有哪些?
      *  dom.onclick = function () {}
      * 事件监听   dom.addEventListener('click',function(){},false)
      * 元素绑定 <div onclick = "load()"></div>
  */

Node.js 事件驱动

  1. 问题: Node.js中有DOM吗?
    • 没有
    • 结论: 原生js DOM 事件都不能用
  2. 创建了一个叫做 events 内置模块来解决这个问题
const events= require('events');
//events.EventEmitter//构造函数
console.log(events.EventEmitter.prototype)//原型链
/* 
 EventEmitter {
    _events: undefined,
    _eventsCount: 0,
    _maxListeners: undefined,
    setMaxListeners: [Function: setMaxListeners],
    getMaxListeners: [Function: getMaxListeners],
    emit: [Function: emit],
    addListener: [Function: addListener],
    on: [Function: addListener],
    prependListener: [Function: prependListener],
    once: [Function: once],
    prependOnceListener: [Function: prependOnceListener],
    removeListener: [Function: removeListener],
    off: [Function: removeListener],
    removeAllListeners: [Function: removeAllListeners],
    listeners: [Function: listeners],
    rawListeners: [Function: rawListeners],
    listenerCount: [Function: listenerCount],
    eventNames: [Function: eventNames]
  }
*/
const archetype=events.EventEmitter.prototype;
// archetype.on(事件,事件处理函数)  作用发布
// archetype.emit(事件名,实际参数)     作用订阅
archetype.on('handler',(val)=>{
console.log('事件触发',val);
})
archetype.emit('handler',111)

Readline模块逐行读取文本内容

readline 模块提供了一个接口,用于一次一行地读取可读流(例如 process.stdin)中的数据。

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question('你如何看待 Node.js 中文网?', (answer) => {
  // TODO:将答案记录在数据库中。
  console.log(`感谢您的宝贵意见:${answer}`);

  rl.close();
});
const readline = require('readline');
const fs = require('fs');

const rl = readline.createInterface({
  input: fs.createReadStream('sample.txt')
});

rl.on('line', (line) => {
  console.log('Line from file:', line);
});

简易爬虫

/* 
  * 爬虫
    * 1. 进行数据请求,获取网页内容       http
    * 2. 进行数据分析、数据清洗 
    * 3. 发送给我们自己的网页
*/
const http=require('http')
//获取 JSON 的示例:
http.get('http://jsonplaceholder.typicode.com/albums', (res) => {
     /* res就是我得到的返回值 */
  const { statusCode } = res;//状态码
  const contentType = res.headers['content-type'];//得到的文件类型
// 错误代码处理
  let error;
  if (statusCode !== 200) {
    error = new Error('请求失败\n' +
                      `状态码: ${statusCode}`);
  } else if (!/^application\/json/.test(contentType)) {
    error = new Error('无效的 content-type.\n' +
                      `期望的是 application/json 但接收到的是 ${contentType}`);
  }
  if (error) {
    console.error(error.message);
    // 消费响应数据来释放内存。
    res.resume();//重新发起数据
    return;
  }

  res.setEncoding('utf8');//中文编码
  let rawData = '';//真实数据
  res.on('data', (chunk) => { rawData += chunk; });// 通过data事件将数据分片,然后逐片添加到rawData身上,好处就是当我们执行每一个分片的小任务时,至少给其他任务提供了可执行的机会
  res.on('end', () => {//结束
    try {// 高级编程 错误捕获
      const parsedData = JSON.parse(rawData);
      console.log(parsedData);
    } catch (e) {
      console.error(e.message);
    }
  });
}).on('error', (e) => {
  console.error(`出现错误: ${e.message}`);
});
const http=require('http');
const cheerio=require('cheerio')
const options={
    hostname: 'jx.1000phone.net',
  port: 80,
  path: '/teacher.php/Class/classDetail/param/rqiWlsefmajGmqJhXXWhl3ZiZ2Zn',
  method: 'GET',
  headers: {
    Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
    'Cache-Control': 'no-cache',
    Connection: 'keep-alive',
    Cookie: 'PHPSESS,
    Host: 'jx.1000phone.net',
    Pragma: 'no-cache',
    Referer: 'http://jx.1000phone.net/teacher.php/Class/index',
    'Upgrade-Insecure-Requests': 1,
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': 0
  }}

http.get(options, (res) => {
  const { statusCode } = res;
  const contentType = res.headers['content-type'];


  res.setEncoding('utf8');
  let rawData = '';
  res.on('data', (chunk) => { rawData += chunk; });
  res.on('end', () => {
    try {
const $=cheerio.load(rawData);
$('.student a').each(function(item,index){
    console.log($(this).text());
    
})
      
    } catch (e) {
      console.error(e.message);
    }
  });
}).on('error', (e) => {
  console.error(`出现错误: ${e.message}`);
});