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

1 确定爬取目标

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

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

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

2 写一个Node爬虫

2.1 探寻网站风格

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

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

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

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

我们就可以发现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 总结

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

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

总结:从Node爬取数据到前端图表展示的更多相关文章

  1. node.js爬取数据并定时发送HTML邮件

    node.js是前端程序员不可不学的一个框架,我们可以通过它来爬取数据.发送邮件.存取数据等等.下面我们通过koa2框架简单的只有一个小爬虫并使用定时任务来发送小邮件! 首先我们先来看一下效果图 差不 ...

  2. 借助Chrome和插件爬取数据

    工具 Chrome浏览器 TamperMonkey ReRes Chrome浏览器 chrome浏览器是目前最受欢迎的浏览器,没有之一,它兼容大部分的w3c标准和ecma标准,对于前端工程师在开发过程 ...

  3. Node爬取简书首页文章

    Node爬取简书首页文章 博主刚学node,打算写个爬虫练练手,这次的爬虫目标是简书的首页文章 流程分析 使用superagent发送http请求到服务端,获取HTML文本 用cheerio解析获得的 ...

  4. Python使用Scrapy框架爬取数据存入CSV文件(Python爬虫实战4)

    1. Scrapy框架 Scrapy是python下实现爬虫功能的框架,能够将数据解析.数据处理.数据存储合为一体功能的爬虫框架. 2. Scrapy安装 1. 安装依赖包 yum install g ...

  5. web scraper——简单的爬取数据【二】

    web scraper——安装[一] 在上文中我们已经安装好了web scraper现在我们来进行简单的爬取,就来爬取百度的实时热点吧. http://top.baidu.com/buzz?b=1&a ...

  6. 关于js渲染网页时爬取数据的思路和全过程(附源码)

    于js渲染网页时爬取数据的思路 首先可以先去用requests库访问url来测试一下能不能拿到数据,如果能拿到那么就是一个普通的网页,如果出现403类的错误代码可以在requests.get()方法里 ...

  7. 【Spider】使用CrawlSpider进行爬虫时,无法爬取数据,运行后很快结束,但没有报错

    在学习<python爬虫开发与项目实践>的时候有一个关于CrawlSpider的例子,当我在运行时发现,没有爬取到任何数据,以下是我敲的源代码:import scrapyfrom UseS ...

  8. 【个人】爬虫实践,利用xpath方式爬取数据之爬取虾米音乐排行榜

    实验网站:虾米音乐排行榜 网站地址:http://www.xiami.com/chart  难度系数:★☆☆☆☆ 依赖库:request.lxml的etree (安装lxml:pip install ...

  9. python模拟浏览器爬取数据

    爬虫新手大坑:爬取数据的时候一定要设置header伪装成浏览器!!!! 在爬取某财经网站数据时由于没有设置Header信息,直接被封掉了ip 后来设置了Accept.Connection.User-A ...

随机推荐

  1. SpringMVC的数据回现

    一.什么是数据回显 数据提交后,如果出现错误,将刚才提交的数据回显到刚才的提交页面. 二.pojo数据回显方法 1.springmvc默认对pojo数据进行回显. pojo数据传入controller ...

  2. 解决IntelliJ IDEA导入本地项目不能切换github容器的问题

    问题场景: 复制本地一个github项目到IDEA中,本地项目容器是A,新项目的容器仍然是A. 解决方法: 1.打开项目在资源管理器中的位置,隐藏的文件项目查看√上,删掉.git文件夹. 2. 3.选 ...

  3. Java入门系列-23-NIO(使用缓冲区和通道对文件操作)

    NIO 是什么 java.nio全称java non-blocking(非阻塞) IO(实际上是 new io),是指jdk1.4 及以上版本里提供的新api(New IO) ,为所有的原始类型(bo ...

  4. no jpeg in java.library.path;java.lang.NoClassDefFoundError: Could not initialize class sun.awt.image.codec.JPEGImageEncoderImpl

    no jpeg in java.library.path;java.lang.NoClassDefFoundError: Could not initialize class sun.awt.imag ...

  5. SSO单点登录的实现原理是怎样的

    单点登录在现在的系统架构中广泛存在,他将多个子系统的认证体系打通,实现了一个入口多处使用,而在架构单点登录时,也会遇到一些小问题,在不同的应用环境中可以采用不同的单点登录实现方案来满足需求.我将以我所 ...

  6. kd-tree 小结

    核心思想 是一种分割 \(k\) 维数据空间的数据结构 一维情况下就是平衡树,以 \(key\) 为标准判断插入左儿子还是右儿子 \(kdtree\) 就是平衡树在多维空间的扩展 因为有多维,我们按不 ...

  7. 记一次bug修复过程

    我的建议,究竟有谁会看,以我的位置,到底能推动到哪一层可行性,可能性 问题:用户的数据丢失了.以为是修改操作 有bug,但查看了后端接口和前端校验,都没有发现问题.但是input数据没有日志[日志级别 ...

  8. java--多线程之后台线程

    public class ThreadDaemon { /** * @param args * 后台线程在主进程结束后,也会退出 */ public static void main(String[] ...

  9. 项目管理系列--好用的代码评审(Code Review)工具

    1. Gerrit Gerrit is a web based code review system, facilitating online code reviews for projects us ...

  10. 解决github无法访问的问题

     gitbub是外网,经常会遇到访问不了的问题,并且有时能访问也网速好慢. 解决这个问题的方法是 更改hosts文件,地址: C:\Windows\System32\Drivers\etc 我在hos ...