ライフハック

スクレイピングでmac製品をカートに入れる・・・を試して修正した

元記事です

PuppeteerでスクレイピングしてMacBook Pro整備済製品をカートに入れる!もう逃さない!
https://qiita.com/iwamooo/items/4f47d17704cd9b4f1de9

なんか、Appleのサイトの仕様が変わってるらしくて、うまく動きませんでした。

const puppeteer = require('puppeteer')
const notifier = require('node-notifier')

const getMacbook = setInterval(() => {
  !(async() => {
    try {
      const browser = await puppeteer.launch({ 
        //executablePath: '/usr/bin/chromium-browser',
        args: ['--no-sandbox'],
    headless:true })
      const page = await browser.newPage()
      await page.waitFor(5000)

      // ページアクセス
      await page.goto('https://www.apple.com/jp/shop/refurbished/mac')

      /**
       * findItem
       *
       * @return {object}
       */
      const findItem = await page.evaluate(() => {
        let result = {}
        const nodeList = document.querySelectorAll('.as-producttile-tilelink')

        for (let i = 0; nodeList.length > i; i++) {
          const target = nodeList[i].innerText

          const check_1 = 'Mac Mini 2.8GHzデュアルコアIntel Core i5 [整備済製品]'
          /* const check_2 = '2017年6月発売モデル' */

          if (target.indexOf(check_1) !== -1 /*&& target.indexOf(check_2) !== -1 */) {
            result.isHit = true
            result.itemNumber = i + 1

            console.log(result.itemNumber);

            break
          }
        }

        return result
      })

      if (findItem.isHit) {
        // ログイン部分のDOM読み込み(isLogin)
        await page.click('#ac-gn-bag > a')
        await page.waitFor(5000)

        /**
         * isLogin
         *
         * @return {boolean}
         */
        const isLogin = await page.evaluate(() => {
          const findItem = document.querySelectorAll('.ac-gn-bagview-nav-item-signIn')
          return findItem.length ? false : true
        })

        if (!isLogin) {
          // ページ移動
          await page.click('.ac-gn-bagview-nav-link-signIn')
          await page.waitForNavigation()

          // ログイン情報設定
          await page.type('input[name="login-appleId"]', 'Apple ログインID');
          await page.type('input[name="login-password"]', 'パスワード');

          // ログイン
          await page.click('#sign-in')
          await page.waitForNavigation()

          // ログイン部分のDOM読み込み(isCartEmpty)
          await page.click('#ac-gn-bag > a')
          await page.waitFor(5000)

          /**
           * isCartEmpty
           *
           * @return {boolean}
           */
          const isCartEmpty = await page.evaluate(() => {
            const findItem = document.querySelectorAll('.ac-gn-bagview-message-empty')

            return findItem.length ? true : false
          })

          if (isCartEmpty) {
            // ページ移動
            
            await page.click(`.as-gridpage-producttiles li:nth-child(${findItem.itemNumber}) .as-producttile-tilelink`)
            //await page.click(.box-content > table:nth-child(${findItem.itemNumber}) .product > .purchase-info > a`)
            await page.waitFor('.form-submit-btn', {
              timeout: 120000
            })

            // カートに追加
            await page.click('.form-submit-btn button')

            // デスクトップ通知
            notifier.notify({
              'title': 'アイテムヒット!',
              'message': 'カートに追加したよ!'
            })

            console.log('カートに追加したよ!')
          } else {
            console.log('もうカートにあるよ!')
            clearInterval(getMacbook)
          }
        }
      } else {
        console.log('みつからないなー。。。')
      }

      browser.close()
    } catch (e) {
      console.error(e)
    }
  })()
}, 60000)

問題点は、検索ワードがぴったりあってないと動かないっぽいところです。
正規表現とかである程度幅を持たせとかないと逃す気がする。
すごくテストしとかないと信頼性がないですねー。

あと、サイトの仕様が変わってるとうまく動きませんね・・・

応用で何かできないか考えてみたいと思います。
あと、上記コード試すときはAppleに負荷かけないように心がけて試してくださいー。