当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 使用 Node.js 开发资讯爬虫流程

使用 Node.js 开发资讯爬虫流程

2018年02月02日  | 移动技术网IT编程  | 我要评论

最近项目需要一些资讯,因为项目是用 node.js 来写的,所以就自然地用 node.js 来写爬虫了

项目地址:github.com/mrtanweijie… ,项目里面爬取了 readhub 、 开源中国 、 开发者头条 、 36kr 这几个网站的资讯内容,暂时没有对多页面进行处理,因为每天爬虫都会跑一次,现在每次获取到最新的就可以满足需求了,后期再进行完善

爬虫流程概括下来就是把目标网站的html下载到本地再进行数据提取。

一、下载页面

node.js 有很多http请求库,这里使用 request ,主要代码如下:

requestdownloadhtml () {
 const options = {
  url: this.url,
  headers: {
  'user-agent': this.randomuseragent()
  }
 }
 return new promise((resolve, reject) => {
  request(options, (err, response, body) => {
  if (!err && response.statuscode === 200) {
   return resolve(body)
  } else {
   return reject(err)
  }
  })
 })
 }

使用 promise 来进行包装,便于后面使用的时候用上 async/await 。因为有很多网站是在客户端渲染的,所以下载到的页面不一定包含想要的html内容,我们可以使用 google 的 puppeteer 来下载客户端渲染的网站页面。众所周知的原因,在 npm i 的时候 puppeteer 可能因为需要下载chrome内核导致安装会失败,多试几次就好了:)

puppeteerdownloadhtml () {
 return new promise(async (resolve, reject) => {
  try {
  const browser = await puppeteer.launch({ headless: true })
  const page = await browser.newpage()
  await page.goto(this.url)
  const bodyhandle = await page.$('body')
  const bodyhtml = await page.evaluate(body => body.innerhtml, bodyhandle)
  return resolve(bodyhtml)
  } catch (err) {
  console.log(err)
  return reject(err)
  }
 })
 }

当然客户端渲染的页面最好是直接使用接口请求的方式,这样后面的html解析都不需要了,进行一下简单的封装,然后就可以像这样使用了: #滑稽 :)

await new downloader('http://36kr.com/newsflashes', downloader.puppeteer).downloadhtml()

二、html内容提取

html内容提取当然是使用神器 cheerio 了, cheerio 暴露了和 jquery 一样的接口,用起来非常简单。浏览器打开页面 f12 查看提取的页面元素节点,然后根据需求来提取内容即可

readhubextract () {
 let nodelist = this.$('#itemlist').find('.enablevisited')
 nodelist.each((i, e) => {
  let a = this.$(e).find('a')
  this.extractdata.push(
  this.extractdatafactory(
   a.attr('href'),
   a.text(),
   '',
   sourcecode.readhub
  )
  )
 })
 return this.extractdata
 }

三、定时任务

cron 每天跑一跑 
function job () {
 let cronjob = new cron.cronjob({
 crontime: cronconfig.crontime,
 ontick: () => {
  spider()
 },
 start: false
 })
 cronjob.start()
}

四、数据持久化

数据持久化理论上应该不属于爬虫关心的范围,用 mongoose ,创建model

import mongoose from 'mongoose'
const schema = mongoose.schema
const newsschema = new schema(
 {
 title: { type: 'string', required: true },
 url: { type: 'string', required: true },
 summary: string,
 recommend: { type: boolean, default: false },
 source: { type: number, required: true, default: 0 },
 status: { type: number, required: true, default: 0 },
 createdtime: { type: date, default: date.now }
 },
 {
 collection: 'news'
 }
)
export default mongoose.model('news', newsschema)

基本操作

import { obj_status } from '../../constants'
class baseservice {
 constructor (objmodel) {
 this.objmodel = objmodel
 }

 saveobject (objdata) {
 return new promise((resolve, reject) => {
  this.objmodel(objdata).save((err, result) => {
  if (err) {
   return reject(err)
  }
  return resolve(result)
  })
 })
 }
}
export default baseservice

资讯

import baseservice from './baseservice'
import news from '../models/news'
class newsservice extends baseservice {}
export default new newsservice(news)

愉快地保存数据

await newsservice.batchsave(newslisttem)

更多内容到github把项目clone下来看就好了。

总结

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网