這篇文章主要介紹了使用 Node.js 開發資訊爬蟲流程,爬蟲流程概括下來就是把目標網站的HTML下載到本地再進行資料擷取。具體內容詳情大家參考下本文
最近專案需要一些資訊,因為專案是用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()
2、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下來看就好了。
總結
上面是我整理給大家的,希望今後會對大家有幫助。
相關文章:
以上是使用Node.js如何實作資訊爬蟲(詳細教學)的詳細內容。更多資訊請關注PHP中文網其他相關文章!