node爬虫入门

232 阅读1分钟

这是我参与「掘金日新计划 · 4 月更文挑战」的第 7 天,点击查看活动详情

这一篇的内容是写一个可以运行起来,满足基本使用的爬虫程序,对于相对高级一点的反爬策略、分布式爬取等技术未有涉及。

声明:示例中使用到的网站为掘金主站,该网站允许被爬虫爬取网页内容。

爬虫的基本思路

  1. 确定要抓取的URL,发起http请求得到页面HTML,进而获取到你希望得到的信息

  2. 对获取的结构进行分析并存储;

两个重要的模块

我们使用node.js来进行爬虫的实现,主要使用requestcheerio两个包:

  1. request : 对http进行封装,提供更多、更方便的接口供我们使用,request进行的是异步请求。
  2. cheerio : 类似于jQuery,可以使用$(),find(),text(),html()等方法提取页面中的元素和数据。

使用它们就可以轻松实现一个网络爬虫。

robots协议

那么为什么网页可以被爬取呢?什么样的爬取方式是合法的呢?

网页可以爬取,也需要被爬取,这样才能被搜索引擎收录并且获得良好的搜索排名结果。

但爬虫容易被滥用,别人的网站是否能够被爬取呢?对方能够接收我们爬取哪些内容呢?这就不得不提到一个专门规定这些内容的rotots协议。

robots.txt是一个文本文件,也是一个协议,它是爬虫要查看的第一个文件,告知爬虫在服务器上什么文件是可以被查看的,爬虫需要按照该文件中的内容来确定访问的范围。

比如我们来看一下掘金的robots协议是什么:

网站位置: www.juejin.cn/robots.txt/… ,使用浏览器打开可以看到具体的内容:

image.png

可以看到它是允许爬取任何内容的,这样我们就可以放心进行爬取了。

爬虫系统的开发环境准备(node)

需要的基础包

express

request

cheerio:转换和分析DOM树

安装依赖

安装express脚手架,用来快熟生成experss项目

npm install express express-generator -g

创建项目

express spider

安装requestcheerio

npm install request cheerio --save-dev

非必要但是进阶需要的包

安装supervisor,用来做进程守护,如果我们的node服务意外中断了,它可以帮我们自动重启:

yum install supervisor

安装nodemon,用来做热更新,假如我们修改了代码,它会帮我们重新运行服务,不用我们手动重新运行:

npm install -g nodemon

第一个爬虫实例

我们先来获取一个简单的网页,就以掘金首页的header头为例:

image.png

我们要获取的就是.main-header-box下的html内容:

const request = require('request');
const cheerio = require('cheerio');

request('https://juejin.cn/',function(err,response,body){
  if( !err && response.statusCode == 200 ){
    const $ = cheerio.load(body);
    // 输出导航的HTML代码
    console.log( $('.main-header-box').html() );
  }
});

运行项目:node demo1.js

可以看到获取到的内容就是<header>标签下的内容:

image.png

获取指定标签内容,并将结果输出到网页上:

这次我们使用nodemon启动第二个实例:

启动项目:

nodemon demo2.js

demo2.js

const express = require('express')
const app = express()
const port = 3000
const request = require('request');
const cheerio = require('cheerio');

app.get('/', (req, res) => {
        request('https://juejin.cn/', function (error, response, body) {
          const $ = cheerio.load(body);
          if(!error && response.statusCode == 200){
                res.json({
                        'Classnum':$('.nav-item').length
                })
          }
        });
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

查看结果:

image.png