zoukankan      html  css  js  c++  java
  • 总结:从Node爬取数据到前端图表展示

    nodejs

    最近寒假在家学习Node.js开发,光看书或者跟着敲代码还不够,得找一点有趣的事情来玩一玩,于是我决定写一个Node爬虫,爬取一些有意思或者说是有用的数据。这个决定只与我的兴趣有关,与Python或者Node或者Java等等谁更适合写爬虫无关,与爬取多少数据无关,与爬取的对象无关。

    1 确定爬取目标

    在写Node爬虫之前,我们先要确定爬取的网站目标。

    这个目标的选择有一定的标准,首先得具有可行性,必须能够爬取到这个网站上的数据,否则一切都是空谈;其次,网站上数据的真实性或者数据量必须满足你的需求;最后,网站的响应速度也是我们需要考虑的一个因素。

    基于这些标准,我选择了智联招聘网站作为我的爬取目标,爬取的数据是全国主要城市的主要软件工作岗位的招聘数据。

    2 写一个Node爬虫

    2.1 探寻网站风格

    确定爬取目标之后,我们就可以着手写Node爬虫了。由于每一个网站的代码风格不同,我们针对不同网站所写的爬虫也会不同。

    在写爬虫之前,我们需要先查看一下智联招聘网站的url风格,以及代码风格。

    image

    在智联招聘的首页,我们可以发现一个搜索栏,填入工作和地点之后,我们就可以点击搜索查看对应招聘信息,这时候我们可以探究一下智联招聘url中暗藏的秘密。当我选择珠海城市的Web开发岗位的时候,我的url是下图这样的:

    image

    多试几次,或者把鼠标放在下图中的链接上。

    image

    我们就可以发现url中参数的意义所在。

    其他参数我们不用管,我们只需要知道sj是岗位代码,p是当前数据页码(搜索结果可能有很多页,智联招聘是每页60条记录),jl是城市就可以了。知道这两个参数的意义之后,我们就可以通过组合url来获取不同城市不同岗位的招聘信息了。

    2.2 解析HTML文本

    在Node中组合url,然后通过http模块的get方法,我们可以获取到来自智联招聘网站的响应。

    function getData(pageNo, job, jobLocation, jobsCount){
        var url = encodeURI(`http://sou.zhaopin.com/jobs/searchresult.ashx?bj=160000&sj=${variables.jobs[job]}&in=160400&jl=${jobLocation}&p=${pageNo}&isadv=0`);    
        var jobs = [];
        console.log(`${job}-${jobLocation}...`);
        return new Promise((resolve, reject)=>{
            try{
                http.get(url, (res)=>{
    

    不难发现我们得到的响应是一个html文件,我们可以通过解析html文本来获取其中的数据信息。最直接的方法是通过RegExp,但是获取的信息较多时会比较麻烦。

    我选择的是通过第三方库——cheerio,来解析HTML文本。这个库使用起来简单方便,能够让你在V8引擎中通过jQuery操作DOM节点的方式解析HTML文本信息。

    $('table.newlist').each((k, v)=>{
                            var job = {};
                            job.company = $('td.gsmc', v).text();
                            job.salary = $('td.zwyx', v).text();
                            job.name = String($('td.zwmc>div', v).text()).replace(/s/g, '');
                            job.location = jobLocation;
                            if(job.company !== '' && job.salary !== '面议'){
                                jobs.push(job);
                            }
                        });
    

    上面这段代码就是我通过cheerio解析HTML文本的代码。

    在同时发起多个请求时,有可能会漏掉一些请求,我认为是并发太多导致服务器没有响应,应该通过setTimeout函数延迟一下多个请求。这一点在我将处理后的数据存到LeanCloud平台时得到了验证。

    3 存储爬取到的数据

    我选择的是MongoDB作为我的后台数据库,因为MongoDB以文档形式存储数据,数据格式是BSON,与Node.js的亲和性很好。

    MongoDB操作简单,性能很高,能够满足我的开发需求。

    在官网下载MongoDB的Windows安装包之后(需要科学上网),在Windows平台安装,最好不要安装自带的可视化工具,因为会消耗相当长的时间,我们可以选择Robo 3T作为替代品。其他安装过程可以自行百度。

    我们在Node中使用MongoDB需要先通过MongoDB Driver,我选择的是mongodb。

    通过

    npm install mongodb --save
    

    就可以安装,然后在Node代码中通过

    require('mongodb')
    

    引入。

    存储代码:

    const MongoClient = require('mongodb').MongoClient;
    //将数据写入数据库
    function writeDB(type, realJobs){
        MongoClient.connect('mongodb://localhost:27017', (e, db)=>{
            assert.ifError(e);
            var jobs = db.db('jobs');
            var collection = jobs.collection('jobs');
            realJobs.forEach((job)=>{
                collection.insert(Object.assign({}, job, { type }));
            });
            db.close();
        });
    }
    

    4 通过Node解析数据

    通过爬虫获取的数据还只是原始数据,我需要通过Node将其转化为我需要的数据,比如对深圳的Web前端开发岗位薪资取平均值。

    这一过程简而言之就是将数据从MongoDB中取出来,然后取平均值。处理之后的代码我将它们存到了LeanCloud上,以便于我的前端展示页面调用。

    5 前端页面展示

    我使用React框架写前端页面,综合React Router插件实现客户端路由,后台数据存储在LeanCloud上,通过LeanCloud的SDK即可在前端页面实现数据查询。

    图表的展示我使用echarts插件,这款插件由百度团队开发,使用起来已经不比highcharts差了,性能方面表现感觉很出色。

    6 总结

    这次开发极大地增强了我的学习兴趣,通过爬取的数据我也对软件行业在各城市的发展有了一定的了解。这一次从后端到前端的开发,让我学到了新的知识,也复习了之前学习过的旧知识,受益匪浅。

    文章发表在我的个人博客,欢迎访问!

  • 相关阅读:
    javascript实战演练,制作新按钮,‘新窗口打开网站’,点击打开新窗
    P1332 血色先锋队
    P4643 [国家集训队]阿狸和桃子的游戏
    T149876 公约数
    P1462 通往奥格瑞玛的道路
    P1083 借教室
    Tribles UVA
    Fence Repair POJ
    Crossing Rivers
    关于一轮
  • 原文地址:https://www.cnblogs.com/DM428/p/8444396.html
Copyright © 2011-2022 走看看