Node.js获取疫情数据并写入数据库mysql中

一、准备环境

安装好Node.js
新建一个文件夹
新建一个js文件 spider

二、代码时间

1.首先引入相关模块

// 目标是获取某网站的疫情数据
const superagent = require('superagent')
const cheerio = require('cheerio')
const mysql =require('mysql')
const path = require('path')
var schedule = require('node-schedule');
//schedule模块用来执行定时任务 
const request=require('request');

2.创建数据库连接


var connection ;

//创建数据库连接
//创建一个函数handleError,负责防止mysql断连

function handleError () {
  connection = mysql.createConnection({
    host:'localhost',
    port:端口号,//安装数据库默认端口号为3306
    user:"Mysql用户名",
    password:"Mysql密码",
    database:"你的数据库名称"
  });
 
  //连接错误,2秒重试
  connection.connect(function (err) {
      if (err) {
          console.log('error when connecting to db:', err);
          setTimeout(handleError , 2000);
      }
  });

  connection.on('error', function (err) {
      console.log('db error', err);
      // 如果是连接断开,自动重新连接
      if (err.code === 'PROTOCOL_CONNECTION_LOST') {
          handleError();
      } else {
          throw err;
      }
  });
}
handleError();//执行函数

3.获取当前时间

//获取当天的时间
var getToday=function(){
var time=new Date();
var year=time.getFullYear();
var day=time.getDate();
if(day<10){
  day='0'+day;
}
var month=time.getMonth()+1;
if(month<10){
  month='0'+month;
}
var date=year+'-'+month+'-'+day;
return date
}

4.第一个执行函数

1.这个定时任务是负责获取数据,存入数据库中
2.先用superagent请求页面获得html
3.然后用cheerio解析html,可以通过jQuery的方法操作dom,获得里面的数据
4.获得数据之后,就写入数据库的alldata2数据表


var spider=function(){
  // 1. 请求目标网站
const url = `https://ncov.dxy.cn/ncovh5/view/pneumonia`
superagent
  .get(url)
  .then(res => {
    // console.log(res.text) // 相应的内容
    // 浏览器可以解析html 但是node端不行
    // 2. 去解析html字符串从里面提取对应疫情数据
    const $ = cheerio.load(res.text) // 然后后我们就可以通过jQuery的方法操作dom
    // 获取全国疫情信息数据

    var $getAreaStat = $('#getAreaStat').html()

    // console.log($getListByCountryTypeService1)
    // 使用字符切割 正则匹配 eval函数
    var dataObj = {}

    eval($getAreaStat.replace(/window/g, 'dataObj'))

    //console.log(dataObj)
    // 3. fs写入数据到本地
        var date=getToday();

        var getAreaStat=dataObj.getAreaStat;
        var arr=[]
        getAreaStat.forEach(item => {   
            var provinceCode=item.locationId;
            var result=item.cities;
            //console.log(result);
            if(result.length==0){
              var addSql = 'INSERT INTO alldata2(id,date,province,provinceCode,city,cityCode,confirmed,suspected,cured,dead) VALUES(0,?,?,?,?,?,?,?,?,?)';
              var cityCode=provinceCode;
              var province=item.provinceName;
              var city=province;
              var confirmed=item.confirmedCount;
              var suspected=item.suspectedCount;
              var cured=item.curedCount;
              var dead=item.deadCount;
              var addSqlParams = [date,province,provinceCode,city,cityCode,confirmed,suspected,cured,dead];
              //alldata
              connection.query(addSql, addSqlParams, function (err, result) {
                  if (err) {
                      console.log('[INSERT ERROR-] - ', err.message);
                      return;
                  }
              }); 
            }else{
              result.forEach(res=>{
              var addSql = 'INSERT INTO alldata2(id,date,province,provinceCode,city,cityCode,confirmed,suspected,cured,dead) VALUES(0,?,?,?,?,?,?,?,?,?)';
              var cityCode=res.locationId
              var province=item.provinceName;
              var city=res.cityName;
              var confirmed=res.confirmedCount;
              var suspected=res.suspectedCount;
              var cured=res.curedCount;
              var dead=res.deadCount;
              var addSqlParams = [date,province,provinceCode,city,cityCode,confirmed,suspected,cured,dead];
              //alldata
              connection.query(addSql, addSqlParams, function (err, result) {
                  if (err) {
                      console.log('[INSERT ERROR-] - ', err.message);
                      return;
                  }
              });   
            })
          }
            
        })
      console.log('写入数据成功!')


  })
  .catch(err => {
    throw err
  })
}

5.第二个执行函数

1.读取之前写入alldata2数据表的数据
2.请求高德地图的api获取地理坐标
3.写入location2数据表


var spider2=function(){
 var date=getToday();
  var strings="SELECT * FROM `alldata2` WHERE date='"+date+"'"
  connection.query(strings,  function (err, result) {
  if (err) {
      console.log('[INSERT ERROR-] - ', err.message);
      return;
  }else{
      //console.log(result);
      const sleep = function (ms){
          return new Promise(resolve => setTimeout(resolve, ms))
        }
        const requestData = async function(){
          for(var i=0;i<result.length;i++){
              var city=result[i].city;
              var province=result[i].province;
              var provinceCode=result[i].provinceCode;
              var cityCode=result[i].cityCode;
              var confirmed=result[i].confirmed;
              var url='https://restapi.amap.com/v3/geocode/geo?address='+province+city+'&output=JSON&key=你申请的地址匹配的key'
              //console.log(url);
              request(encodeURI(url),function (error, response, body) {
                  var data =JSON.parse(body)
                  var location=data.geocodes[0].location;
                  //console.log(location)
                  var lng=location.split(',')[0];
                  lng=parseFloat(lng)
                  var lat=location.split(',')[1];
                  lat=parseFloat(lat)
                  var addSql2 = 'INSERT INTO location2(id,date,province,provinceCode,city,cityCode,confirmed,lng,lat) VALUES(0,?,?,?,?,?,?,?,?)';
                  var addSqlParams2 = [date,province,provinceCode,city,cityCode,confirmed,lng,lat];
                  connection.query(addSql2, addSqlParams2, function (err, result) {
                      if (err) {
                          console.log('[INSERT ERROR-] - ', err.message);
                          return;
                      }
                  }); 
              })
              await sleep(200);//每一个循环休息0.2s}
              
          }
        }
        requestData();
  }
  }); 

}

6.为两个执行函数创建定时任务


var runSchedule =function (cb) {
    // cron风格的配置:每天上午2点05分执行一次第一个函数
    schedule.scheduleJob('0 5 2 * * *', function () {
        var time=new Date();
        var year=time.getFullYear();
        var day=time.getDate();
        var month=time.getMonth()+1;
        console.log('spider定时任务执行一次'+year+'年'+month+'月'+day+'日');
            cb && cb();
    });
}

//可以按照cron的格式设置
var runSchedule2 =function (cb) {
    // cron风格的配置:每天上午2点10分执行一次第二个函数
    schedule.scheduleJob('0 10 2 * * *', function () {
      var time=new Date();
        var year=time.getFullYear();
        var day=time.getDate();
        var month=time.getMonth()+1;
        console.log('spider2定时任务执行一次'+year+'年'+month+'月'+day+'日');
          cb && cb();
    });
}
 runSchedule(spider);
 runSchedule2(spider2);

 console.log('定时任务已启动');

7.全部代码

// // 目标是获取网站的疫情数据
const superagent = require('superagent')
const cheerio = require('cheerio')
const mysql =require('mysql')
const path = require('path')
var schedule = require('node-schedule');
//schedule模块用来执行定时任务 
const request=require('request');
// superagent.get(url).then()
var connection ;

//创建数据库连接
function handleError () {
  connection = mysql.createConnection({
    host:'localhost',
    port:端口号,//安装数据库默认端口号为3306
    user:"Mysql用户名",
    password:"Mysql密码",
    database:"你的数据库名称"
  });
 
  //连接错误,2秒重试
  connection.connect(function (err) {
      if (err) {
          console.log('error when connecting to db:', err);
          setTimeout(handleError , 2000);
      }
  });

  connection.on('error', function (err) {
      console.log('db error', err);
      // 如果是连接断开,自动重新连接
      if (err.code === 'PROTOCOL_CONNECTION_LOST') {
          handleError();
      } else {
          throw err;
      }
  });
}
handleError();

//获取当天的时间
var getToday=function(){
var time=new Date();
var year=time.getFullYear();
var day=time.getDate();
if(day<10){
  day='0'+day;
}
var month=time.getMonth()+1;
if(month<10){
  month='0'+month;
}
var date=year+'-'+month+'-'+day;
return date
}



var spider=function(){
  // 1. 请求目标网站
const url = `https://ncov.dxy.cn/ncovh5/view/pneumonia`
superagent
  .get(url)
  .then(res => {
    // console.log(res.text) // 相应的内容
    // 浏览器可以解析html 但是node端不行
    // 2. 去解析html字符串从里面提取对应疫情数据
    const $ = cheerio.load(res.text) // 然后后我们就可以通过jQuery的方法操作dom
    // 获取全国疫情信息数据

    var $getAreaStat = $('#getAreaStat').html()

    // console.log($getListByCountryTypeService1)
    // 使用字符切割 正则匹配 eval函数
    var dataObj = {}

    eval($getAreaStat.replace(/window/g, 'dataObj'))

    //console.log(dataObj)
    // 3. fs写入数据到本地
        var date=getToday();

        var getAreaStat=dataObj.getAreaStat;
        var arr=[]
        getAreaStat.forEach(item => {   
            var provinceCode=item.locationId;
            var result=item.cities;
            //console.log(result);
            if(result.length==0){
              var addSql = 'INSERT INTO alldata2(id,date,province,provinceCode,city,cityCode,confirmed,suspected,cured,dead) VALUES(0,?,?,?,?,?,?,?,?,?)';
              var cityCode=provinceCode;
              var province=item.provinceName;
              var city=province;
              var confirmed=item.confirmedCount;
              var suspected=item.suspectedCount;
              var cured=item.curedCount;
              var dead=item.deadCount;
              var addSqlParams = [date,province,provinceCode,city,cityCode,confirmed,suspected,cured,dead];
              //alldata
              connection.query(addSql, addSqlParams, function (err, result) {
                  if (err) {
                      console.log('[INSERT ERROR-] - ', err.message);
                      return;
                  }
              }); 
            }else{
              result.forEach(res=>{
              var addSql = 'INSERT INTO alldata2(id,date,province,provinceCode,city,cityCode,confirmed,suspected,cured,dead) VALUES(0,?,?,?,?,?,?,?,?,?)';
              var cityCode=res.locationId
              var province=item.provinceName;
              var city=res.cityName;
              var confirmed=res.confirmedCount;
              var suspected=res.suspectedCount;
              var cured=res.curedCount;
              var dead=res.deadCount;
              var addSqlParams = [date,province,provinceCode,city,cityCode,confirmed,suspected,cured,dead];
              //alldata
              connection.query(addSql, addSqlParams, function (err, result) {
                  if (err) {
                      console.log('[INSERT ERROR-] - ', err.message);
                      return;
                  }
              });   
            })
          }
            
        })
      console.log('写入数据成功!')


  })
  .catch(err => {
    throw err
  })
}

//spider();


var spider2=function(){
 var date=getToday();
  var strings="SELECT * FROM `alldata2` WHERE date='"+date+"'"
  connection.query(strings,  function (err, result) {
  if (err) {
      console.log('[INSERT ERROR-] - ', err.message);
      return;
  }else{
      //console.log(result);
      const sleep = function (ms){
          return new Promise(resolve => setTimeout(resolve, ms))
        }
        const requestData = async function(){
          for(var i=0;i<result.length;i++){
              var city=result[i].city;
              var province=result[i].province;
              var provinceCode=result[i].provinceCode;
              var cityCode=result[i].cityCode;
              var confirmed=result[i].confirmed;
              var url='https://restapi.amap.com/v3/geocode/geo?address='+province+city+'&output=JSON&key=a36e6768d9262fcb339a50ce016a5caa'
              //console.log(url);
              request(encodeURI(url),function (error, response, body) {
                  var data =JSON.parse(body)
                  var location=data.geocodes[0].location;
                  //console.log(location)
                  var lng=location.split(',')[0];
                  lng=parseFloat(lng)
                  var lat=location.split(',')[1];
                  lat=parseFloat(lat)
                  var addSql2 = 'INSERT INTO location2(id,date,province,provinceCode,city,cityCode,confirmed,lng,lat) VALUES(0,?,?,?,?,?,?,?,?)';
                  var addSqlParams2 = [date,province,provinceCode,city,cityCode,confirmed,lng,lat];
                  connection.query(addSql2, addSqlParams2, function (err, result) {
                      if (err) {
                          console.log('[INSERT ERROR-] - ', err.message);
                          return;
                      }
                  }); 
              })
              await sleep(200);//每一个循环休息0.2s}
              
          }
        }
        requestData();
  }
  }); 

}

//spider2();


// 创建两个定时任务,第一个任务执行spider函数爬取数据存到数据库中
// 第二个定时任务执行spider2函数,将数据库中的爬取数据 读取出来进行处理,添加地理坐标,再次存到数据库中,获得有地理坐标的数据
var runSchedule =function (cb) {
    // cron风格的配置:每天上午两点05分执行一次
    schedule.scheduleJob('0 5 2 * * *', function () {
        var time=new Date();
        var year=time.getFullYear();
        var day=time.getDate();
        var month=time.getMonth()+1;
        console.log('spider定时任务执行一次'+year+'年'+month+'月'+day+'日');
            cb && cb();
    });
}

//可以按照cron的格式设置
var runSchedule2 =function (cb) {
    // cron风格的配置:每天上午2.10点执行一次
    schedule.scheduleJob('0 10 2 * * *', function () {
      var time=new Date();
        var year=time.getFullYear();
        var day=time.getDate();
        var month=time.getMonth()+1;
        console.log('spider2定时任务执行一次'+year+'年'+month+'月'+day+'日');
          cb && cb();
    });
}
 runSchedule(spider);
 runSchedule2(spider2);

 console.log('定时任务已启动');


三、启动程序

在文件夹空白处,按住键盘ctrl键+鼠标右键 打开cmd命令行:
输入

cnmp i //安装依赖 也就是开头说的库
node spider //安装完所有依赖,执行程序,不关闭cmd就会一直每天爬取了

四、数据表格式

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GIS_宇宙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值