price-task.js 2.38 KB
const dayjs = require('dayjs');
const nodeLockup = require('node-lockup');
const spider = require('../libs/spider');
const {logger} = require('../libs/logger');
const fs = require('fs');
const _ = require('lodash');


const REG_HOUR = /^[1,2]小时/;
const REG_MINUES = /^\d+分钟/;

const fetchBuys = async(productId, lsId = 0) => {
  let lastList = [];
  const result = await spider.spiderFetch(productId, 'https://du.hupu.com/mapi/product/lastSoldList', {
    lastId: lsId
  });

  if (result.status === 200) {
    const {list, lastId} = result.data;

    lastList = list.filter(info => {
      return REG_HOUR.test(info.formatTime) || REG_MINUES.test(info.formatTime) || info.formatTime.indexOf('刚刚') >= 0;
    });

    if (lastList.length) {
      const nextList = await fetchBuys(productId, lastId);

      lastList = lastList.concat(nextList);
    }
  }

  return lastList;
};

const processBuys = async(data) => {
  const allList = await fetchBuys(data.productId);

  data.sizes.forEach(size => {
    const buys = allList.filter(info => {
      return info.item && info.item.size === size.size;
    });

    size.soldNum += buys.length;
  });

  return data;
};


const task = async(id) => {
  const result = await spider.spiderFetch(id);

  if (result.status === 200) {
    const {detail, sizeList} = result.data;

    const productId = detail.productId;
    const soldNum = detail.soldNum;
    const sizes = sizeList.map(sizeItem => {
      return {
        size: sizeItem.size,
        price: _.isEmpty(sizeItem.item) ? 0 : sizeItem.item.price,
        soldNum: 0
      };
    });

    const dest = await processBuys({
      productId,
      soldNum,
      sizes
    });

    return dest;
  }
};

module.exports = async() => {
  const now = dayjs().format('YYYY-MM-DD_HH');
  const fw = fs.createWriteStream(`/Data/logs/node/prices/${now}.log`, {
    flags: 'a'
  });
  const lockTask = nodeLockup(task, 1);

  const ids = Array.from(new Array(22080)).map((v, i) => i + 1);

  try {
    ids.forEach((id, inx) => {
      lockTask(id).then(async result => {
        if (result) {

          logger.info(`time:${now}; productId:${id}; soldNum:${result.soldNum}; sizeSoldNum:${_.sumBy(result.sizes, 'soldNum')}`);

          fw.write(`${JSON.stringify(result)}\n`);
        }
        if (inx >= ids.length - 1) {
          fw.end('');
        }
      });
    });
  } catch (error) {
    fw.end(error.toString());
  }
};