LoginSignup
13
14

More than 5 years have passed since last update.

ディズニーストアの人気商品を手に入れる方法

Last updated at Posted at 2014-10-01

ディズニーストアの人気商品を手に入れる方法

前提

奥さんはディズニーの「ラプンツェル」というキャラクターが好きだ。

ある日「ディズニーストアで販売している『ラプンツェルLEDライト』という商品がどうしても欲しいんだけどいつも売り切れてて・・・再入荷したらアラートが来るようにできないか?」という相談を受けた。

まずは敵を知る

ディズニーストアにはオンラインショップがあるので、まずは要素を見てみる。

そこでわかった重要なことは以下の3点だ。※2014年10月01日 時点

  • 公式には入荷アラートの機能は存在しない。
  • 商品にはそれぞれ固定のURLが存在する。
  • 在庫がある商品には、購入数を選択するセレクトボックスと購入ボタンが存在する。

ここまでわかればこっちのものだ。

攻略法(仕様)を決める

cronで定期的に商品ページをスクレイピングして、在庫があるときにだけでる要素が存在すればメールでアラートすることにする。

  • 10分に1回処理を実行。
  • 在庫があるかの確認は、購入数を選択するときにだけ表示される「数量」という文字があるかどうかで行う。
  • メールが何回も送られてくるのは嫌なので1度だけ送るようにする。
  • 深夜のメールは迷惑なので、7時から25時までの間だけメールを送るようにする。
  • 今後別の商品でも同じ要望があるかもしれないので、「商品の指定」と「在庫チェック」は分離して実装する。

実装

disneystore_check.php
<?php

$id      = 1;
$url     = "http://www.disneystore.co.jp/shop/ProductDetail.aspx?sku=4936313635065&CD=F3000283&WKCD=";
$name    = "ラプンツェルLEDライト";

$checker = new StockChacker($id, $url, $name);
$checker->run();

class StockChacker {

    const AGENT    = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36";

    const ENC_FROM = "SJIS";
    const ENC_TO   = "UTF-8";

    const KEYWORD  = "数量";

    const PID_DIR  = "/tmp/cron/disneystore";

    private $id;
    private $url;
    private $name;

    public function __construct($id, $url, $name) {
        $this->id   = $id;
        $this->url  = $url;
        $this->name = $name;
    }

    public function existsPid() {
        return file_exists(sprintf(static::PID_DIR . "/%s.pid", $this->id));
    }

    public function makePid() {
        touch(sprintf(static::PID_DIR . "/%s.pid", $this->id));
    }

    public function run() {
        if ($this->existsPid()) {
            return;
        }

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $this->url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_USERAGENT, static::AGENT);
        $res = curl_exec($curl);
        curl_close($curl);

        $res = mb_convert_encoding($res, static::ENC_TO, static::ENC_FROM);

        if (!strpos($res, static::KEYWORD)) {
            return;
        }

        mb_language('ja');
        mb_internal_encoding('UTF-8');
        mb_send_mail(
            "宛先",
            sprintf("%s入荷中", $this->name),
            $this->url,
            "From: 差出人"
        );

        $this->makePid();
    }

}
crontab.txt
*/10 0,7-23 * * * php disneystore_check.php

結果

無事に購入できました。
※真ん中下にあるやつ。

IMG_2673.JPG

13
14
0

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
13
14