Skip to content

Instantly share code, notes, and snippets.

@jef
Last active July 29, 2022 15:28
Show Gist options
  • Star 41 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save jef/96fd50c6fe3eedc1bdf52585eac2b3c4 to your computer and use it in GitHub Desktop.
Save jef/96fd50c6fe3eedc1bdf52585eac2b3c4 to your computer and use it in GitHub Desktop.
const puppeteer = require("puppeteer");
const opn = require("opn");
const nodemailer = require("nodemailer");
const timeout = 5000;
const waitForTimeout = 1000;
const cartLink =
"https://store.nvidia.com/store/nvidia/en_US/buy/productID.5438481700/clearCart.yes/nextPage.QuickBuyCartPage";
const emailUsername = process.env.EMAIL_USERNAME;
const emailPassword = process.env.EMAIL_PASSWORD;
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: emailUsername,
pass: emailPassword,
},
});
const mailOptions = {
from: emailUsername,
to: emailUsername,
subject: "NVIDIA - BUY NOW",
text: cartLink,
};
async function buy() {
const links = [
"https://www.nvidia.com/en-us/geforce/buy/",
"https://www.nvidia.com/en-us/shop/geforce/?page=1&limit=9&locale=en-us&search=3080",
"https://www.bestbuy.com/site/nvidia-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-graphics-card-titanium-and-black/6429440.p?skuId=6429440",
];
for (const link of links) {
await goto(link);
}
setTimeout(buy, timeout);
}
async function goto(link) {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setUserAgent(
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
);
page.setViewport({
width: 1920,
height: 1080,
});
await page.goto(link);
await page.waitFor(waitForTimeout);
const dom = await page.evaluate(() => {
return {
body: document.body.innerText,
};
});
console.log(dom);
if (dom.body.toLowerCase().includes("out of stock") || dom.body.toLowerCase().includes("sold out")) {
console.log("still out of stock, will try again.");
} else {
console.log("*** IN STOCK, BUY NOW ***");
await page.screenshot({ path: `nvidia-${Date.now()}.png` });
opn(cartLink);
if (emailUsername && emailPassword) {
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
} else {
console.log("email sent: " + info.response);
}
});
}
}
await browser.close();
}
try {
buy();
} catch (error) {
buy();
}
@Michael-Keen-MS
Copy link

Does anyone have a better way to check for stock? I was sending a get request to https://api-prod.nvidia.com/direct-sales-shop/DR/products/en_us/USD/5438481600 which would return a json response which would tell you inventory status, but now it doesn't work so well (error 503 - gateway times out).

Nvidia's own website makes the same website and now it fails there too, but eventually after a while the out of stock button pops up on their site. Do you guys think their website is setup so that if the request fails the out of stock button shows up? Or is their a better way to check for stock?

import requests

url = "https://api-prod.nvidia.com/direct-sales-shop/DR/products/en_us/USD/5438481600"

payload = {}
headers = {
  'authority': 'api-prod.nvidia.com',
  'accept': 'application/json, text/javascript, */*; q=0.01',
  'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36',
  'dnt': '1',
  'origin': 'https://www.nvidia.com',
  'sec-fetch-site': 'same-site',
  'sec-fetch-mode': 'cors',
  'sec-fetch-dest': 'empty',
  'referer': 'https://www.nvidia.com/en-us/geforce/graphics-cards/30-series/rtx-3090/',
  'accept-language': 'en-CA,en-GB;q=0.9,en-US;q=0.8,en;q=0.7'
}

response = requests.request("GET", url, headers=headers, data = payload)

print(response.text.encode('utf8'))

This should help:

from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>"))

import requests
import json

payload = {}
headers = {
  'authority': 'api-prod.nvidia.com',
  'accept': 'application/json, text/javascript, */*; q=0.01',
  'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36',
  'dnt': '1',
  'origin': 'https://www.nvidia.com',
  'sec-fetch-site': 'same-site',
  'sec-fetch-mode': 'cors',
  'sec-fetch-dest': 'empty',
  'referer': 'https://www.nvidia.com/en-us/geforce/graphics-cards/30-series/rtx-3090/',
  'accept-language': 'en-CA,en-GB;q=0.9,en-US;q=0.8,en;q=0.7'
}

url = "https://api-prod.nvidia.com/direct-sales-shop/DR/products/en_us/USD/5438481700"

response = requests.request("GET", url, headers=headers, data = payload)

/* print(response.json()) -- you can use this to look at the full dict */

jsonResponse = response.json()

for url in jsonResponse["products"]["product"]:
    print(" PRODUCT NAME:   ", url["displayName"], '\n', "IN STOCK?:      ", url["inventoryStatus"]["productIsInStock"].upper(), '\n', "PRODUCT STATUS: ", url["inventoryStatus"]["status"], '\n', "PRICE:          ", url["pricing"]["formattedListPrice"])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment