LoginSignup
2
6

More than 3 years have passed since last update.

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

Last updated at Posted at 2018-09-12

目的

ヤフオク検索の自動化をしたく作成しました。
私はこのスクリプトと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;

2
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6