From 9fd5b51f24853fbd5db7493c3164ee5dd943c3e1 Mon Sep 17 00:00:00 2001 From: Jared Chapiewsky Date: Tue, 4 Dec 2018 14:20:16 -0600 Subject: [PATCH] add pagination --- .env.example | 5 +-- CHANGELOG.md | 28 ++++++++++------ README.md | 8 +++-- index.js | 94 ++++++++++++++++++++++++++++++++++------------------ package.json | 2 +- 5 files changed, 88 insertions(+), 49 deletions(-) diff --git a/.env.example b/.env.example index ac33748..a477a6b 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,3 @@ -AMAZON_USERNAME=fake@example.com -AMAZON_PASSWORD=123456 +AMAZON_USERNAME=fake@example.com +AMAZON_PASSWORD=123456 +HEADLESS=1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eeaf25..29e3386 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,17 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 0.0.1 - 2018-12-03 -### Added -- This CHANGELOG file -- Basic working script -- README file +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.1.0 - 2018-12-04 +### Added +- add page iteration +- tells you if you didn't win +- ability to run headless or not + +## 0.0.1 - 2018-12-03 +### Added +- This CHANGELOG file +- Basic working script +- README file diff --git a/README.md b/README.md index 74d1345..a16cbc0 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This script will loop through all your Amazon giveaways and try to submit entries for them. -**WIP** - "no entry requirement" giveaways are implemented for first page. Need to include page iteration next. +**WIP** - Only "no entry requirement" giveaways are implemented. Wanted a reason to experiment with puppeteer, so here goes. @@ -11,8 +11,10 @@ Wanted a reason to experiment with puppeteer, so here goes. Copy .env.example to .env, adding your own Amazon username and password. ```javascript -$ NPM install -$ NPM start +$ npm install +$ npm start ``` Check the console to see how things are going. + +To run in browser, change `HEADLESS=0` in .env file to `HEADLESS=1`. diff --git a/index.js b/index.js index 351327f..566df43 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,9 @@ +#! /usr/bin/env node + /*global process, console */ require('dotenv').config(); const puppeteer = require('puppeteer'); - async function asyncForEach(array, callback) { for (let index = 0; index < array.length; index++) { await callback(array[index], index, array); @@ -10,38 +11,15 @@ async function asyncForEach(array, callback) { } async function navigateBackToGiveaways(page) { - const navigationPromise = page.waitForNavigation(); - await page.waitForSelector('#giveaway-default-return-link-button'); - await page.click('#giveaway-default-return-link-button'); - return await navigationPromise; + //const navigationPromise = page.waitForNavigation(); + //await page.waitForSelector('#giveaway-default-return-link-button'); + //await page.click('#giveaway-default-return-link-button'); + return await page.goBack(); } -(async () => { - const browser = await puppeteer.launch({headless: false}); - const page = await browser.newPage(); - - //sign in - await page.goto('https://www.amazon.com/ap/signin?_encoding=UTF8&ignoreAuthState=1&openid.assoc_handle=usflex&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.max_auth_age=0&openid.return_to=https%3A%2F%2Fwww.amazon.com%2Fgp%2Fgiveaway%2Fhome%2Fref%3Dnav_custrec_signin&switch_account='); - const username = process.env.AMAZON_USERNAME; - const password = process.env.AMAZON_PASSWORD; - - await page.waitForSelector('#ap_email'); - await page.click('#ap_email'); - await page.type('#ap_email', username); - - await page.waitForSelector('#ap_password'); - await page.click('#ap_password'); - await page.type('#ap_password', password); - - const signInPromise = page.waitForNavigation(); - await page.waitForSelector('#signInSubmit'); - await page.click('#signInSubmit'); - await signInPromise; - - //go to giveaways - await page.goto('https://www.amazon.com/ga/giveaways'); - +async function enterGiveaways(page, pageNumber) { //loop through each giveaway item + console.log('Page ' + pageNumber + ' Start:'); const giveawayKeys = new Array(24); await asyncForEach(giveawayKeys, async (val, index) => { let i = index + 1; @@ -75,8 +53,12 @@ async function navigateBackToGiveaways(page) { } //try to win! + console.log('waiting for box...'); await page.waitForSelector('#box_click_target'); - await page.click('#box_click_target'); + await page.click('#box_click_target', {delay: 2000}); + const resultTextEl = await page.waitForSelector('.qa-giveaway-result-text'); + const resultText = await page.evaluate(resultTextEl => resultTextEl.textContent, resultTextEl); + console.log(resultText); await navigateBackToGiveaways(page); } else { @@ -84,7 +66,55 @@ async function navigateBackToGiveaways(page) { } }); - //TODO: go to next page... + //go to next page, if we can + try { + await page.waitForSelector('.a-section > #giveawayListingPagination > .a-pagination > .a-last > a'); + } catch(e) { + console.log('No more pages! Goodbye!'); + return; + } + + const navigationPromise = page.waitForNavigation(); + await page.click('.a-section > #giveawayListingPagination > .a-pagination > .a-last > a'); + await navigationPromise; + + console.log('Next Page!'); + await enterGiveaways(page, pageNumber + 1); +} + +async function signIn(page, username, password) { + await page.goto('https://www.amazon.com/ap/signin?_encoding=UTF8&ignoreAuthState=1&openid.assoc_handle=usflex&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.max_auth_age=0&openid.return_to=https%3A%2F%2Fwww.amazon.com%2Fgp%2Fgiveaway%2Fhome%2Fref%3Dnav_custrec_signin&switch_account='); + + await page.waitForSelector('#ap_email'); + await page.click('#ap_email'); + await page.type('#ap_email', username); + + await page.waitForSelector('#ap_password'); + await page.click('#ap_password'); + await page.type('#ap_password', password); + + const signInPromise = page.waitForNavigation(); + await page.waitForSelector('#signInSubmit'); + await page.click('#signInSubmit'); + await signInPromise; +} + +//start index code +(async () => { + const headless = (process.env.HEADLESS === 1); + const browser = await puppeteer.launch({headless: headless}); + const page = await browser.newPage(); + + //sign in + const username = process.env.AMAZON_USERNAME; + const password = process.env.AMAZON_PASSWORD; + await signIn(page, username, password); + + //go to giveaways + await page.goto('https://www.amazon.com/ga/giveaways?pageId=50'); + + //enter giveaways + await enterGiveaways(page, 1); await browser.close(); })(); diff --git a/package.json b/package.json index f92091d..fcd1e79 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "giveaway-grabber", - "version": "0.0.1", + "version": "0.1.0", "description": "Automates entries for Amazon Giveaways", "main": "index.js", "scripts": {