使用Node.js实现简单的爬虫

写在前头

最近Node.js时觉得Node.js的异步操作很适合写爬虫,然后就萌生了写爬虫这一决定。

准备阶段

第一步:选择需要爬的网页的url :(https://movie.douban.com/subject/26752088/?from=showing)
第二步:确定页面的demo结构。
第三步:使用https向网页发送请求,获取网页的数据进行分析。
第四步:对数据进行处理
第五步:从上一步信息中提取信息,然后保存下来。

开始阶段

第一步:
安装Node.js。
第二步:
命令行输入npm init建立项目目录。
使用npm安装cherrio包(可以使爬下来的数据用类似jQuery的方式处理)【https://www.npmjs.com/package/cheerio】;
使用npm安装request包(用于发送简单的请求)【https://www.npmjs.com/package/request】
第三步:
构建项目结构:

项目结构

tools文件夹用来存放工具函数
index.js为入口文件
package.json为包管理文件

第三步:编写代码
首先,我们需要个工具函数(mkdir)创建两个文件夹(data和img)分别保存我们爬到的文字内容和图片。
在tools目录创建mkdir.js文件,内容如下。

const fs = require('fs') //引入fs

module.exports = function mkdir(list) {
  //list为要创建的文件夹名字
  fs.stat(list, function(err, stats) {
    //异步建立文件
    if (!stats) {
      //若文件不存在,则创建文件
      fs.mkdir(list, function(err) {
        if (err) {
          console.log(err) //若创建过程有问题 就报错
        }
      })
      console.log(`创建了${list}文件夹`)
    }
  })
}

接着我们就要创建工具函数(fetchData)来发送请求,并保存我们需要的东西。
在tools目录下创建fetchData.js文件,内容如下:

const https = require('https') //引入https模块
const cheerio = require('cheerio') //引入cheerio
const save = require('./save') //引入save函数

module.exports = function fetchData(url) {
  console.log('working')
  https.get(url, function(res) {
    //发送请求
    var html = '' //获取html
    res.on('data', function(chunk) {
      html += chunk
    })
    res.on('end', function() {
      const $ = cheerio.load(html) //使用cheeio处理html
      const movie_info = {
        //获取dom中相应元素的值
        name: $('#content>h1')
          .text()
          .replace(/\s/g, ''), //除去空格
        imgUrl: $('#mainpic > a > img').attr('src'),
        summary: $('#link-report span[property="v:summary"]')
          .text()
          .replace(/\s/g, '') //除去空格
      }
      save(movie_info) //使用save函数保存内容
    })
    res.on('error', err => console.log(err)) //若请求错误则报错
  })
}

接着我们就要创建fetchData中用于保存的工具函数(save)。
在tools目录下创建save.js文件,内容如下:

const fs = require('fs') //引入fs
const saveImg = require('./saveImg') //引入saveImg函数

module.exports = function save(movie_info) {
  const text = JSON.stringify(movie_info) //stringify化
  fs.appendFile('./data/' + movie_info.name + '.txt', text, function(err) {
    //创建.txt文件保存相关内容
    if (err) {
      console.log(err)
    }
  })
  saveImg(movie_info.name, movie_info.imgUrl) //引用保存图片的saveImg函数来保存图片
}

接着我们就要创建save中用于保存图片的工具函数(saveImg)。
在tools目录下创建saveImg.js文件,内容如下:

const request = require('request') //引入request
const fs = require('fs') //引入fs

module.exports = function saveImg(img_title, img_url) {
  const img_filename = img_title + '.jpg'
  request.head(img_url, function(err, res, body) {
    //判断图片是否存在
    if (err) {
      console.log(err)
    }
  })
  request.get(img_url).pipe(fs.createWriteStream('./img/' + img_title + '.jpg'))
  //获取图片并保存
}

最后一步在根目录下写入口文件index.js,内容如下:

const https = require('https')
const fs = require('fs')
const request = require('request')
const cheerio = require('cheerio')
const mkdir = require('./tools/mkdir')
const fetchData = require('./tools/fetchData')

mkdir('./img/') //创建img文件夹

mkdir('./data/') //创建data文件夹

fetchData(process.argv[2]) //获取参数URL发送请求

最后在命令行敲

node index https://movie.douban.com/subject/26752088/?from=showing

然后看你的结果吧。

结语

因为临近期末考试了,只能随便写写了。下一步的优化是把数据存入数据库,然后再建立一次爬多页面的功能。
源码地址:https://github.com/Tevils/node-splider

你可能感兴趣的:(使用Node.js实现简单的爬虫)