继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Egg.js 采集最新的省市数据

lockLuck
关注TA
已关注
手记 6
粉丝 4
获赞 16

网站上经常会使用省市区数据,正好最近正在学习Egg.js,于是就尝试Egg.js采集统计局上面的数据。

搭建环境

$ mkdir egg-example
$ cd egg-example
$ npm init
$ npm i egg --save
$ npm i egg-bin --save-dev

添加 npm scripts 到 package.json:

{
  "name": "egg-example",
  "scripts": {
    "dev": "egg-bin dev"
  }
}

编写 Controller
我们第一步需要编写的是 Controller 和 Router。

// app/controller/home.js
const Controller = require('egg').Controller;
class HomeController extends Controller {
  async index() {
    this.ctx.body = 'Hello world';
  }
}
module.exports = HomeController;

配置路由映射:

// app/router.js
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
};

加一个配置文件:

// config/config.default.js
exports.keys = <此处改为你自己的 Cookie 安全字符串>;

此时目录结构如下:

egg-example
├── app
│   ├── controller
│   │   └── home.js
│   └── router.js
├── config
│   └── config.default.js
└── package.json

现在可以启动应用来体验下

$ npm run dev
$ open localhost:7001

html结构

分析页面结构,页面2018年统计用区划代码和城乡划分代码
其中关于城市的的截图:
图片描述

代码结构如下:
图片描述

假如用Jquery ,可以这样获取数据:

$('.provincetr').each(function(i,tr){
   $(tr).children().each(function(j,td){
      console.log($(td).text());                    //省份名称
      console.log($(td).find('a').attr('href'))     //市区内容链接
   })
});

获取到的省份以及包含市区内容链接:
图片描述

然后在抓取市区页面去得到市区的列表,
比如:http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2018/13.html 是河北省的所有城市的内容。

以此类推,直至获取到所有需要的数据。

工具

cheerio是一个以jquery语法为核心的服务器爬虫库,大部分的用法和Jquery很相似。

npm i cheerio --save

iconv-lite 防止乱码,目标页面的编码gb2312。

npm i iconv-lite --save

开发

首先在app/controller/ 下新建一个area.js,该控制器用来获取数据,代码如下:

const Controller = require('egg').Controller;
var cheerio = require('cheerio');
var iconv = require('iconv-lite');
//基础链接
const baseUrl="http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2018/";
class AreaController extends Controller {
  async getArea() {
     const province =await this.getProvince();
     await this.getCity(province);
     this.ctx.body=province;
  }
  async getProvince(){
    var me=this;
    let url=baseUrl+'index.html';       //页面地址
    let provice=[];                     //存储数据
    const {data}=await this.ctx.curl(url);    //抓取页面
    let $ = cheerio.load(iconv.decode(data,'gb2312'));
    $('.provincetr').each(function(i,tr){
       $(tr).children().each(function(j,td){      //解析数据
          var name=$(td).text();
          var link=$(td).find('a').attr('href');
          let obj={
            name:name,
            code:link.substr(0,2),
            children:[]
          };
          provice.push(obj);
       });
    });

    return provice;
  }
  async getCity(province){
    for(let i=0;i<province.length;i++){
      let cityLink=baseUrl+province[i].code+'.html';
      const {data}=await this.ctx.curl(cityLink);
      let $ = cheerio.load(iconv.decode(data,'gb2312'));
      $('.citytr').each(function(i,tr){
        var code=$(tr).find('td').first().text();
        var name=$(tr).find('td').last().text();
        var link=$(tr).find('a').attr('href');
        let obj={
          name:name,
          code:code,
        };
        province[i].children.push(obj);
      });
    }
  }
}

module.exports = AreaController;

修改router.js 的代码:

router.get('/', controller.area.getArea);

访问:http://localhost:7001
最终获取的数据格式:
图片描述

这里只介绍了获取省市的代码,其他获取更多的数据可以自行添加。

打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP

热门评论

基于egg.js的后台开发框架、权限管理、前后端分离 vue.js  https://www.cool-admin.com

查看全部评论