├── .gitignore ├── files ├── start.sh ├── crontab.txt └── stock_checker.py ├── docker-compose.yaml ├── README.md ├── Dockerfile └── Buy Bot - RTX GPU.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /files/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd /home && /usr/local/bin/python stock_checker.py &>>/tmp/yeelight_rtx_stock_checker.log 4 | -------------------------------------------------------------------------------- /files/crontab.txt: -------------------------------------------------------------------------------- 1 | 30 17 * * * /home/start.sh >> /var/log/cron.log 2>&1 2 | # An empty line is required at the end of this file for a valid cron file. 3 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | services: 3 | yeelight-stock-checker: 4 | container_name: yeelight-stock-checker 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | network_mode: host 9 | restart: always -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # yeelight-nvidia-rtx-ryzen-stock-checker 2 | Simple Python script that can run in a Raspberry PI and uses Python, BeautifulSoup, Pandas and the Yeelight API to check for the stock availability of the latest Nvidia RTX and Ryzen graphics/cards and CPUs respectively 3 | 4 | 5 | Watch this video to understand the code: 6 | 7 | https://www.youtube.com/watch?v=j7KBhsBr51Y 8 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8-rc-slim-buster 2 | 3 | RUN TZ=Europe/London && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 4 | RUN apt-get -y update && apt-get -y install cron 5 | RUN pip3 install yeelight 6 | RUN pip3 install requests 7 | RUN pip3 install bs4 8 | RUN apt-get -y install python3-pandas 9 | RUN pip3 install pandas 10 | COPY files/* /home/ 11 | 12 | #RUN chmod 755 /script.sh /entry.sh 13 | RUN /usr/bin/crontab /home/crontab.txt 14 | 15 | # Run the command on container startup 16 | RUN touch /var/log/cron.log 17 | 18 | CMD cron && tail -f /var/log/cron.log -------------------------------------------------------------------------------- /files/stock_checker.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import pandas as pd 4 | import requests 5 | from bs4 import BeautifulSoup 6 | import yeelight.transitions 7 | from yeelight import * 8 | from yeelight import discover_bulbs, Bulb 9 | from yeelight import Flow, transitions 10 | from yeelight.flow import Action 11 | from multiprocessing import Process 12 | import pandas as pd 13 | import time 14 | import requests 15 | import sys 16 | 17 | def setupStockAvailableFlow(bulbIp, durationFlowSeconds=60): 18 | try: 19 | bulb = Bulb(bulbIp) 20 | 21 | durationPulseInMs=200 22 | count = (durationFlowSeconds * 1000) / durationPulseInMs 23 | transitionsP = yeelight.transitions.pulse(0, 255, 0, durationPulseInMs, 100) 24 | flow = Flow( 25 | count=count, 26 | action=Action.recover, 27 | transitions=transitionsP 28 | ) 29 | bulb.turn_on() 30 | bulb.start_flow(flow) 31 | # except: 32 | # print("Error setting flow in bulb",file=sys.stderr) 33 | except Exception as ex: 34 | logging.exception("Something awful happened!") 35 | 36 | # starts thread 37 | def startStockAvailableAlert(): 38 | bulbs = discover_bulbs() 39 | for b in bulbs: 40 | print("starting {}".format(b['ip'])) 41 | bulbIp = b['ip'] 42 | print(f"bulbIp:{bulbIp}") 43 | p = Process(target=setupStockAvailableFlow, args=(bulbIp,)) 44 | p.start() 45 | p.join() 46 | 47 | def checkForStock(page): 48 | # soup = BeautifulSoup(wd.page_source) 49 | soup = BeautifulSoup(page.content,features="html.parser") 50 | items = soup.find("div", {"class": "items-grid-view"}) 51 | 52 | items_processed = [] 53 | 54 | for row in items.findAll("div"): 55 | row_processed = [] 56 | itemTitle = row.find("a", {"class": "item-title"}) 57 | itemPromoText = row.find("p", {"class": "item-promo"}) 58 | 59 | status = "Available" 60 | 61 | if itemPromoText and itemPromoText.text == "OUT OF STOCK": 62 | status = "Sold Out" 63 | 64 | if itemTitle: 65 | row_processed.append(itemTitle.text) 66 | row_processed.append(status) 67 | 68 | if row_processed: 69 | items_processed.append(row_processed) 70 | # cells[3].find("img"valid)["src"] 71 | # columns = ["ImageUrl","Origin"] 72 | 73 | df = pd.DataFrame.from_records(items_processed, columns=["Item Title", "Status"]) 74 | 75 | return df 76 | 77 | 78 | 79 | if __name__ == '__main__': 80 | print("Main line start") 81 | # search for RTX 3000 series 82 | URL_NVIDIA_RTX_PAGE1 = 'https://www.newegg.com/p/pl?N=101582767%20601357282' 83 | URL_NVIDIA_RTX_PAGE2 = 'https://www.newegg.com/p/pl?N=101582767%20601357282&page=2' 84 | URL_RYZEN_5000SERIES = "https://www.newegg.com/p/pl?N=101582716%2050001028%20601359163" 85 | URL_RYZEN_THREADRIPPER = "https://www.newegg.com/p/pl?N=100007671%20601350560" 86 | 87 | STOCK_URLS=[URL_NVIDIA_RTX_PAGE1, URL_NVIDIA_RTX_PAGE2, URL_RYZEN_5000SERIES] 88 | 89 | for url in STOCK_URLS: 90 | page = requests.get(url) 91 | stock_df = checkForStock(page) 92 | print(stock_df) 93 | if "Available" in stock_df.Status.values: 94 | print("Stock Available!") 95 | # Switch on lighting to alert 96 | startStockAvailableAlert() 97 | break 98 | else: 99 | print("Everything out of stock!") 100 | time.sleep(5) 101 | print("Main line end") 102 | -------------------------------------------------------------------------------- /Buy Bot - RTX GPU.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "08a1979e", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "from selenium import webdriver as wd\n", 11 | "import chromedriver_binary\n", 12 | "import random\n", 13 | "import time\n", 14 | "import pandas as pd\n", 15 | "from bs4 import BeautifulSoup" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 2, 21 | "id": "5e810b9a", 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "\n", 26 | "wd = wd.Chrome()\n", 27 | "wd.implicitly_wait(10)" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": null, 33 | "id": "daef097b", 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "wd.get(\"https://www.newegg.com/msi-geforce-rtx-3090-rtx-3090-gaming-x-trio-24g/p/N82E16814137595?Description=rtx%203090&cm_re=rtx_3090-_-9SIAMHYD517996-_-Product&quicklink=true\")\n", 38 | "\n", 39 | "#wd.get(\"https://www.newegg.com/asus-geforce-rtx-2060-dual-rtx2060-o6g-evo/p/N82E16814126349?quicklink=true\")" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 3, 45 | "id": "05529634", 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "def checkForStock(url):\n", 50 | " # soup = BeautifulSoup(wd.page_source)\n", 51 | " wd.get(url)\n", 52 | " soup = BeautifulSoup(wd.page_source,features=\"html.parser\")\n", 53 | " items = soup.find(\"div\", {\"class\": \"items-grid-view\"})\n", 54 | "\n", 55 | " items_processed = []\n", 56 | "\n", 57 | " for row in items.findAll(\"div\", {\"class\": \"item-cell\"}):\n", 58 | " row_processed = []\n", 59 | " itemTitle = row.find(\"a\", {\"class\": \"item-title\"})\n", 60 | " itemPromoText = row.find(\"p\", {\"class\": \"item-promo\"})\n", 61 | " itemPrice = row.find(\"li\", {\"class\": \"price-current\"})\n", 62 | "\n", 63 | " \n", 64 | " status = \"Available\"\n", 65 | "\n", 66 | " if itemPromoText and itemPromoText.text == \"OUT OF STOCK\":\n", 67 | " status = \"Sold Out\"\n", 68 | "\n", 69 | " if itemTitle:\n", 70 | " row_processed.append(itemTitle.text)\n", 71 | " row_processed.append(itemPrice.find(\"strong\").text) \n", 72 | " row_processed.append(itemTitle.get(\"href\"))\n", 73 | " row_processed.append(status)\n", 74 | "\n", 75 | " \n", 76 | " if row_processed:\n", 77 | " items_processed.append(row_processed)\n", 78 | " # cells[3].find(\"img\"valid)[\"src\"]\n", 79 | " # columns = [\"ImageUrl\",\"Origin\"]\n", 80 | "\n", 81 | " df = pd.DataFrame.from_records(items_processed, columns=[\"Item Title\",\"Item Price\",\"URL\",\"Status\"])\n", 82 | "\n", 83 | " df[\"Item Price\"] = df[\"Item Price\"].apply(lambda x: x.replace(\",\",\"\"))\n", 84 | " df[\"Item Price\"] = pd.to_numeric(df[\"Item Price\"])\n", 85 | "\n", 86 | " \n", 87 | " return df" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 5, 93 | "id": "b5431d3c", 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "def buyItem(url):\n", 98 | " wd.get(item_to_purchase[\"URL\"])\n", 99 | " add_to_cart_button = wd.find_element_by_xpath('//*[@id=\"ProductBuy\"]/div/div[2]/button')\n", 100 | " add_to_cart_button.click()\n", 101 | " \n", 102 | " random_wait_time = random.randrange(5.0, 15.0)\n", 103 | " print(random_wait_time)\n", 104 | " time.sleep(random_wait_time)\n", 105 | "\n", 106 | " no_thanks_button = wd.find_element_by_xpath('//*[@id=\"modal-intermediary\"]/div/div/div/div[3]/button[1]')\n", 107 | " no_thanks_button.click()\n", 108 | " \n", 109 | " random_wait_time = random.randrange(5.0, 15.0)\n", 110 | " print(random_wait_time)\n", 111 | " time.sleep(random_wait_time)\n", 112 | "\n", 113 | " view_cart_button = wd.find_element_by_xpath('//*[@id=\"modal-intermediary\"]/div/div/div[2]/div[2]/button[2]')\n", 114 | " view_cart_button.click()\n", 115 | " \n", 116 | " random_wait_time = random.randrange(5.0, 15.0)\n", 117 | " print(random_wait_time)\n", 118 | " time.sleep(random_wait_time)\n", 119 | "\n", 120 | "# not_interested_button = wd.find_element_by_xpath('//*[@id=\"Popup_Masks\"]/div/div/div[3]/div[2]/button[1]')\n", 121 | "# not_interested_button.click()\n", 122 | " \n", 123 | " random_wait_time = random.randrange(5.0, 15.0)\n", 124 | " print(random_wait_time)\n", 125 | " time.sleep(random_wait_time)\n", 126 | "\n", 127 | " secure_checkout_button = wd.find_element_by_xpath('//*[@id=\"app\"]/div[1]/section/div/div/form/div[2]/div[3]/div/div/div[3]/div/button')\n", 128 | " secure_checkout_button.click()\n", 129 | " \n", 130 | " random_wait_time = random.randrange(5.0, 15.0)\n", 131 | " print(random_wait_time)\n", 132 | " time.sleep(random_wait_time)\n", 133 | "\n", 134 | " guest_checkout_button = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div[2]/div[2]/div/div/div[1]/form[2]/div[2]/div/button')\n", 135 | " guest_checkout_button.click()\n", 136 | " \n", 137 | " random_wait_time = random.randrange(5.0, 15.0)\n", 138 | " print(random_wait_time)\n", 139 | " time.sleep(random_wait_time)\n", 140 | "\n", 141 | " add_address = wd.find_element_by_xpath('//*[@id=\"app\"]/div/section/div/div/form/div[2]/div[1]/div/div[1]/div/div[2]/div[2]/div/div[2]/div[2]/div/div/i')\n", 142 | " add_address.click()\n", 143 | " \n", 144 | " random_wait_time = random.randrange(5.0, 15.0)\n", 145 | " print(random_wait_time)\n", 146 | " time.sleep(random_wait_time)\n", 147 | "\n", 148 | " first_name = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[1]/input')\n", 149 | " first_name.send_keys(\"Code\")\n", 150 | "\n", 151 | " random_wait_time = random.randrange(5.0, 10.0)\n", 152 | " print(random_wait_time)\n", 153 | " time.sleep(random_wait_time)\n", 154 | "\n", 155 | " last_name = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[2]/input')\n", 156 | " last_name.send_keys(\"Mental\")\n", 157 | "\n", 158 | " random_wait_time = random.randrange(5.0, 10.0)\n", 159 | " print(random_wait_time)\n", 160 | " time.sleep(random_wait_time)\n", 161 | "\n", 162 | " address_first_line = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[6]/input')\n", 163 | " address_first_line.send_keys(\"My house\")\n", 164 | "\n", 165 | " random_wait_time = random.randrange(5.0, 10.0)\n", 166 | " print(random_wait_time)\n", 167 | " time.sleep(random_wait_time)\n", 168 | "\n", 169 | " city = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[8]/input')\n", 170 | " city.send_keys(\"Broomfield\")\n", 171 | "\n", 172 | " random_wait_time = random.randrange(5.0, 10.0)\n", 173 | " print(random_wait_time)\n", 174 | " time.sleep(random_wait_time)\n", 175 | "\n", 176 | " from selenium.webdriver.support.select import Select\n", 177 | " state = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[9]/label[2]/select')\n", 178 | " Select(state).select_by_value('CO')\n", 179 | "\n", 180 | " random_wait_time = random.randrange(5.0, 10.0)\n", 181 | " print(random_wait_time)\n", 182 | " time.sleep(random_wait_time)\n", 183 | "\n", 184 | "\n", 185 | " zip_code = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[10]/input')\n", 186 | " zip_code.clear()\n", 187 | " zip_code.send_keys(\"80021\")\n", 188 | "\n", 189 | " random_wait_time = random.randrange(5.0, 10.0)\n", 190 | " print(random_wait_time)\n", 191 | " time.sleep(random_wait_time)\n", 192 | "\n", 193 | " phone_number = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[12]/input')\n", 194 | " phone_number.send_keys(\"1111111111\")\n", 195 | "\n", 196 | " random_wait_time = random.randrange(5.0, 10.0)\n", 197 | " print(random_wait_time)\n", 198 | " time.sleep(random_wait_time)\n", 199 | "\n", 200 | " email = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[15]/input')\n", 201 | " email.send_keys(\"codemental@example.com\")\n", 202 | "\n", 203 | " random_wait_time = random.randrange(5.0, 10.0)\n", 204 | " print(random_wait_time)\n", 205 | " time.sleep(random_wait_time)\n", 206 | "\n", 207 | " save_button = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[3]/button[2]')\n", 208 | " save_button.click()\n", 209 | " \n", 210 | " random_wait_time = random.randrange(5.0, 15.0)\n", 211 | " print(random_wait_time)\n", 212 | " time.sleep(random_wait_time)\n", 213 | "\n", 214 | " use_address_as_entered = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[3]/button[1]')\n", 215 | " use_address_as_entered.click()\n", 216 | "\n", 217 | " random_wait_time = random.randrange(5.0, 15.0)\n", 218 | " print(random_wait_time)\n", 219 | " time.sleep(random_wait_time)\n", 220 | "\n", 221 | " go_to_delivery_button = wd.find_element_by_xpath('//*[@id=\"app\"]/div/section/div/div/form/div[2]/div[1]/div/div[1]/div/div[3]/button')\n", 222 | " go_to_delivery_button.click()\n", 223 | "\n", 224 | " random_wait_time = random.randrange(5.0, 15.0)\n", 225 | " print(random_wait_time)\n", 226 | " time.sleep(random_wait_time)\n", 227 | "\n", 228 | " go_to_payment_page_button = wd.find_element_by_xpath('//*[@id=\"app\"]/div/section/div/div/form/div[2]/div[1]/div/div[2]/div/div[3]/button')\n", 229 | " go_to_payment_page_button.click()" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 6, 235 | "id": "058677eb", 236 | "metadata": {}, 237 | "outputs": [ 238 | { 239 | "name": "stdout", 240 | "output_type": "stream", 241 | "text": [ 242 | "6\n", 243 | "14\n", 244 | "14\n", 245 | "7\n", 246 | "5\n", 247 | "5\n", 248 | "10\n", 249 | "11\n", 250 | "7\n", 251 | "6\n", 252 | "9\n", 253 | "7\n", 254 | "5\n", 255 | "6\n", 256 | "6\n", 257 | "6\n", 258 | "5\n", 259 | "8\n", 260 | "9\n" 261 | ] 262 | } 263 | ], 264 | "source": [ 265 | "from selenium.common.exceptions import NoSuchElementException\n", 266 | "\n", 267 | "random_wait_time = random.randrange(5.0, 15.0)\n", 268 | "print(random_wait_time)\n", 269 | "time.sleep(random_wait_time)\n", 270 | "\n", 271 | "while (True):\n", 272 | "# try:\n", 273 | " url = \"https://www.newegg.com/p/pl?N=100007709%20601357282\"\n", 274 | " items = checkForStock(url) \n", 275 | " in_stock = items[(items[\"Item Price\"]< 2500) & (items.Status == \"Available\")]\n", 276 | " if not in_stock.empty:\n", 277 | " item_to_purchase = in_stock.iloc[0]\n", 278 | " \n", 279 | " buyItem(item_to_purchase[\"URL\"])\n", 280 | " break\n", 281 | " else:\n", 282 | " time.sleep(120)\n", 283 | "# except NoSuchElementException:\n", 284 | "# print(\"Out of stock\")\n", 285 | "# print(\"waiting for some time....\")\n", 286 | "# time.sleep(120)\n" 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": null, 292 | "id": "e7d35412", 293 | "metadata": {}, 294 | "outputs": [], 295 | "source": [ 296 | "#url = \"https://www.newegg.com/p/pl?N=100007709%20601357248\"\n", 297 | "url = \"https://www.newegg.com/p/pl?N=100007709%20601357282\"\n", 298 | "items = checkForStock(url)\n", 299 | "items" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": null, 305 | "id": "6154d0ae", 306 | "metadata": {}, 307 | "outputs": [], 308 | "source": [ 309 | "items.info()\n", 310 | "\n", 311 | "items[(items[\"Item Price\"]< 2500) & (items.Status == \"Available\")]\n", 312 | "items.head(1)[\"URL\"].loc(0)" 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": null, 318 | "id": "6473ad38", 319 | "metadata": {}, 320 | "outputs": [], 321 | "source": [ 322 | "items.info()\n", 323 | "\n", 324 | "items[\"Item Price\"] = pd.to_numeric(items[\"Item Price\"])" 325 | ] 326 | }, 327 | { 328 | "cell_type": "code", 329 | "execution_count": null, 330 | "id": "095537bf", 331 | "metadata": {}, 332 | "outputs": [], 333 | "source": [ 334 | "items.info()" 335 | ] 336 | }, 337 | { 338 | "cell_type": "code", 339 | "execution_count": null, 340 | "id": "921a372e", 341 | "metadata": {}, 342 | "outputs": [], 343 | "source": [ 344 | "random_wait_time = random.randrange(5.0, 15.0)\n", 345 | "print(random_wait_time)\n", 346 | "time.sleep(random_wait_time)\n", 347 | "\n", 348 | "no_thanks_button = wd.find_element_by_xpath('//*[@id=\"modal-intermediary\"]/div/div/div/div[3]/button[1]')\n", 349 | "no_thanks_button.click()" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": null, 355 | "id": "a93eb91b", 356 | "metadata": {}, 357 | "outputs": [], 358 | "source": [ 359 | "random_wait_time = random.randrange(5.0, 15.0)\n", 360 | "print(random_wait_time)\n", 361 | "time.sleep(random_wait_time)\n", 362 | "\n", 363 | "view_cart_button = wd.find_element_by_xpath('//*[@id=\"modal-intermediary\"]/div/div/div[2]/div[2]/button[2]')\n", 364 | "view_cart_button.click()" 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": null, 370 | "id": "01648db8", 371 | "metadata": {}, 372 | "outputs": [], 373 | "source": [ 374 | "random_wait_time = random.randrange(5.0, 15.0)\n", 375 | "print(random_wait_time)\n", 376 | "time.sleep(random_wait_time)\n", 377 | "\n", 378 | "not_interested_button = wd.find_element_by_xpath('//*[@id=\"Popup_Masks\"]/div/div/div[3]/div[2]/button[1]')\n", 379 | "not_interested_button.click()" 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": null, 385 | "id": "22b1813d", 386 | "metadata": {}, 387 | "outputs": [], 388 | "source": [ 389 | "random_wait_time = random.randrange(5.0, 15.0)\n", 390 | "print(random_wait_time)\n", 391 | "time.sleep(random_wait_time)\n", 392 | "\n", 393 | "secure_checkout_button = wd.find_element_by_xpath('//*[@id=\"app\"]/div[1]/section/div/div/form/div[2]/div[3]/div/div/div[3]/div/button')\n", 394 | "secure_checkout_button.click()" 395 | ] 396 | }, 397 | { 398 | "cell_type": "code", 399 | "execution_count": null, 400 | "id": "f2a29e2d", 401 | "metadata": {}, 402 | "outputs": [], 403 | "source": [ 404 | "random_wait_time = random.randrange(5.0, 15.0)\n", 405 | "print(random_wait_time)\n", 406 | "time.sleep(random_wait_time)\n", 407 | "\n", 408 | "guest_checkout_button = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div[2]/div/div/div[1]/form[2]/div[2]/div/button')\n", 409 | "guest_checkout_button.click()" 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": null, 415 | "id": "dd631455", 416 | "metadata": {}, 417 | "outputs": [], 418 | "source": [ 419 | "random_wait_time = random.randrange(5.0, 15.0)\n", 420 | "print(random_wait_time)\n", 421 | "time.sleep(random_wait_time)\n", 422 | "\n", 423 | "add_address = wd.find_element_by_xpath('//*[@id=\"app\"]/div/section/div/div/form/div[2]/div[1]/div/div[1]/div/div[2]/div[2]/div/div[2]/div[2]/div/div/i')\n", 424 | "add_address.click()" 425 | ] 426 | }, 427 | { 428 | "cell_type": "code", 429 | "execution_count": null, 430 | "id": "6826710a", 431 | "metadata": {}, 432 | "outputs": [], 433 | "source": [ 434 | "random_wait_time = random.randrange(5.0, 15.0)\n", 435 | "print(random_wait_time)\n", 436 | "time.sleep(random_wait_time)\n", 437 | "\n", 438 | "first_name = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[1]/input')\n", 439 | "first_name.send_keys(\"Code\")\n", 440 | "\n", 441 | "random_wait_time = random.randrange(5.0, 10.0)\n", 442 | "print(random_wait_time)\n", 443 | "time.sleep(random_wait_time)\n", 444 | "\n", 445 | "last_name = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[2]/input')\n", 446 | "last_name.send_keys(\"Mental\")\n", 447 | "\n", 448 | "random_wait_time = random.randrange(5.0, 10.0)\n", 449 | "print(random_wait_time)\n", 450 | "time.sleep(random_wait_time)\n", 451 | "\n", 452 | "address_first_line = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[6]/input')\n", 453 | "address_first_line.send_keys(\"My house\")\n", 454 | "\n", 455 | "random_wait_time = random.randrange(5.0, 10.0)\n", 456 | "print(random_wait_time)\n", 457 | "time.sleep(random_wait_time)\n", 458 | "\n", 459 | "city = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[8]/input')\n", 460 | "city.send_keys(\"Broomfield\")\n", 461 | "\n", 462 | "random_wait_time = random.randrange(5.0, 10.0)\n", 463 | "print(random_wait_time)\n", 464 | "time.sleep(random_wait_time)\n", 465 | "\n", 466 | "from selenium.webdriver.support.select import Select\n", 467 | "state = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[9]/label[2]/select')\n", 468 | "Select(state).select_by_value('CO')\n", 469 | "\n", 470 | "random_wait_time = random.randrange(5.0, 10.0)\n", 471 | "print(random_wait_time)\n", 472 | "time.sleep(random_wait_time)\n", 473 | "\n", 474 | "\n", 475 | "zip_code = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[10]/input')\n", 476 | "zip_code.clear()\n", 477 | "zip_code.send_keys(\"80021\")\n", 478 | "\n", 479 | "random_wait_time = random.randrange(5.0, 10.0)\n", 480 | "print(random_wait_time)\n", 481 | "time.sleep(random_wait_time)\n", 482 | "\n", 483 | "phone_number = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[12]/input')\n", 484 | "phone_number.send_keys(\"1111111111\")\n", 485 | "\n", 486 | "random_wait_time = random.randrange(5.0, 10.0)\n", 487 | "print(random_wait_time)\n", 488 | "time.sleep(random_wait_time)\n", 489 | "\n", 490 | "email = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[2]/form/div[2]/div[15]/input')\n", 491 | "email.send_keys(\"codemental@example.com\")\n", 492 | "\n", 493 | "random_wait_time = random.randrange(5.0, 10.0)\n", 494 | "print(random_wait_time)\n", 495 | "time.sleep(random_wait_time)\n", 496 | "\n", 497 | "save_button = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[3]/button[2]')\n", 498 | "save_button.click()" 499 | ] 500 | }, 501 | { 502 | "cell_type": "code", 503 | "execution_count": null, 504 | "id": "26a8b42a", 505 | "metadata": {}, 506 | "outputs": [], 507 | "source": [ 508 | "random_wait_time = random.randrange(5.0, 15.0)\n", 509 | "print(random_wait_time)\n", 510 | "time.sleep(random_wait_time)\n", 511 | "\n", 512 | "use_address_as_entered = wd.find_element_by_xpath('//*[@id=\"app\"]/div/div/div/div/div[3]/button[1]')\n", 513 | "use_address_as_entered.click()\n", 514 | "\n", 515 | "random_wait_time = random.randrange(5.0, 15.0)\n", 516 | "print(random_wait_time)\n", 517 | "time.sleep(random_wait_time)\n", 518 | "\n", 519 | "go_to_delivery_button = wd.find_element_by_xpath('//*[@id=\"app\"]/div/section/div/div/form/div[2]/div[1]/div/div[1]/div/div[3]/button')\n", 520 | "go_to_delivery_button.click()\n", 521 | "\n", 522 | "random_wait_time = random.randrange(5.0, 15.0)\n", 523 | "print(random_wait_time)\n", 524 | "time.sleep(random_wait_time)\n", 525 | "\n", 526 | "go_to_payment_page_button = wd.find_element_by_xpath('//*[@id=\"app\"]/div/section/div/div/form/div[2]/div[1]/div/div[2]/div/div[3]/button')\n", 527 | "go_to_payment_page_button.click()" 528 | ] 529 | } 530 | ], 531 | "metadata": { 532 | "kernelspec": { 533 | "display_name": "Python 3", 534 | "language": "python", 535 | "name": "python3" 536 | }, 537 | "language_info": { 538 | "codemirror_mode": { 539 | "name": "ipython", 540 | "version": 3 541 | }, 542 | "file_extension": ".py", 543 | "mimetype": "text/x-python", 544 | "name": "python", 545 | "nbconvert_exporter": "python", 546 | "pygments_lexer": "ipython3", 547 | "version": "3.8.10" 548 | } 549 | }, 550 | "nbformat": 4, 551 | "nbformat_minor": 5 552 | } 553 | --------------------------------------------------------------------------------