Используйте Node.js для разработки поискового робота

Node.js рептилия
Используйте Node.js для разработки поискового робота

Недавний проект нуждается в некоторой информации, потому чтопроектиспользуетсяNode.jsписать, так что естественно использоватьNode.jsДавайте напишем рептилий

адрес проекта:GitHub.com/Daily Tan Weijie…, залез в проектReadhub,Китай с открытым исходным кодом,Заголовки разработчиков,36KrИнформационное содержание этих веб-сайтов пока не обрабатывается на нескольких страницах, потому что краулер будет запускаться один раз в день, и теперь он может удовлетворять потребности каждый раз, когда он получает последнюю версию, и она будет улучшена позже.

Процесс сканирования можно охарактеризовать как загрузку HTML-кода целевого веб-сайта на локальный сервер и последующее извлечение данных.

1. Страница загрузки

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, создать модель

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 и клонируйте проект, чтобы увидеть его.