Help us understand the problem. What is going on with this article?

Nodejsでヤフオクのオークションアラート

More than 1 year has passed since last update.

目的

ヤフオク検索の自動化をしたく作成しました。
私はこのスクリプトとGoogleAppsScriptを組み合わせて日々のリサーチを自動化しています。

フロー

下記の内容のJSONをサーバーにPOST

postContent.json
{
    "data": {
        "keyword": "ヤフオクで検索するキーワード",
        "limit_purchase_price": "価格上限を指定(任意)",
        "already_checked_auction_ids": "すでにチェック済のオークションIDをカンマ区切りで指定(任意)"
    }
}


サーバーでヤフオクにアクセス・スクレイピングし新しいオークションのIDをカンマ区切りの文字列でreturn

実行環境

・Node.js 8.9.4
・npm 5.6.0
・Heroku上で実装

構造

ファイル数が2つだけなので同じディレクトリです。

ー server.js
ー newAuctionAlert.js

事前準備

・モジュールのインストール

npm_install.cmd
npm install --save express
npm install -save body-parser
npm install --save cheerio-httpcli

コード

server.js

server.js
"use strict";
const express = require('express');
const body_parser = require('body-parser');
const newAuctionAlert = require('./newAuctionAlert');
const app = express();

//***サーバー作成***
const server = app.listen(process.env.PORT || 3000, function() {
    console.log("server listening..");
});

//***express設定***
app.use(body_parser.urlencoded({
    extended: true,
    limit: '5KB'
}));
app.use(body_parser.json({
    limit: '5KB'
}));

//***expressルーティング***
app.post('/newAuctionAlert', async(req, res, next) => {
    const data = req.body.data;
    if (data.keyword) {
        const itemData = JSON.parse(req.body.data);
        const new_auction_ids = await newAuctionAlert.main(data);
        res.status(200).send(new_auction_ids); //カンマ区切り
    } else {
        res.status(404).send('キーワードの指定は必須です');
    }
});

newAuctionAlert.js

newAuctionAlert.js
"use strict";
const cheerio = require('cheerio-httpcli');

async function main(data) {
    return new Promise(async(resolve, reject) => {

        //***1. オークションページのHTMLを取得***
        cheerio.fetch(
            'https://auctions.yahoo.co.jp/search/search', {
                p: data.keyword.replace(/\+/g, ' '), //検索キーワード
                s1: 'end', //残り時間が長い順
                o1: 'd',
                ngram: 1, //あいまい検索
                istatus: 2, //中古のみで検索
                fixed: 0,
                ei: 'UTF-8',
                auccat: 0,
                slider: 0,
                tab_ex: 'commerce',
            }).then((res) => {
            //*** 2. 検索結果が存在すれば、価格が条件にマッチしているものをnew_auction_idsに追加する***
            const enddate_elms = res.$('.ti'); //オークション終了まで○日の部分
            const new_auction_ids = [];
            const already_checked_auction_ids_array = data.already_checked_auction_ids.split(/\,/g);

            if (enddate_elms.first().text() !== "") { //検索結果最上位の終了日を取得 検索結果が無ければ""
                enddate_elms.each(function() {
                    const $parent_dom = res.$(this).parent();
                    const auction_id = $parent_dom.find('.a1wrp').first().find('a').first().attr('href').match(/\/\w+?$/)[0].replace(/^\//, '');

                    //上限価格が設定されている場合は価格チェック
                    var price_flag = true;
                    if (data.limit_purchase_price) {
                        const auction_now_price = Number($parent_dom.find('.pr1').first().text().replace(/\D/g, ''));
                        if (data.limit_purchase_price < auction_now_price) price_flag = false;
                    }
                    //価格がOKですでにチェック済のオークションで無ければ新しいオークション情報として登録
                    if (price_flag && already_checked_auction_ids_array.indexOf(auction_id) === -1) new_auction_ids.push(auction_id);
                });
            }
            resolve(new_auction_ids.join());
        }).catch((e) => {
            reject(e);
        });

    });
}

exports.main = main;

KazukiOkada
FX・物販を自身で行いながら、EA(自動売買)・効率化ツールも開発中。 node.js・shellを使った自動化・効率化が得意です。 たまにフロントエンドも触ります。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away