├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── LICENSE ├── README.md ├── Scripts ├── adidas.py ├── adidas_test.py ├── atclibs.py ├── bodega.py ├── caliroots.py ├── checkstock.py ├── footlocker.py ├── getconf.py ├── ghostdriver.log ├── jimmyjazz.py ├── kithnyc ├── makeinfo.py ├── nakedcph.py ├── overkill.py ├── palaceskateboards.py ├── shiekhshoes.py ├── sneakersnstuff.py ├── supremenewyork.py ├── supremenewyork_v3.py ├── test.py └── userinfo.json └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *swp 2 | *__pycache__ 3 | *pyc 4 | /userinfo.json 5 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Python", 6 | "type": "python", 7 | "request": "launch", 8 | "stopOnEntry": true, 9 | "pythonPath": "/usr/bin/python3.4", 10 | "program": "${file}", 11 | "debugOptions": [ 12 | "WaitOnAbnormalExit", 13 | "WaitOnNormalExit", 14 | "RedirectOutput" 15 | ] 16 | }, 17 | { 18 | "name": "Python Console App", 19 | "type": "python", 20 | "request": "launch", 21 | "stopOnEntry": true, 22 | "pythonPath": "${config.python.pythonPath}", 23 | "program": "${file}", 24 | "externalConsole": true, 25 | "debugOptions": [ 26 | "WaitOnAbnormalExit", 27 | "WaitOnNormalExit" 28 | ] 29 | }, 30 | { 31 | "name": "Django", 32 | "type": "python", 33 | "request": "launch", 34 | "stopOnEntry": true, 35 | "pythonPath": "${config.python.pythonPath}", 36 | "program": "${workspaceRoot}/manage.py", 37 | "args": [ 38 | "runserver", 39 | "--noreload" 40 | ], 41 | "debugOptions": [ 42 | "WaitOnAbnormalExit", 43 | "WaitOnNormalExit", 44 | "RedirectOutput", 45 | "DjangoDebugging" 46 | ] 47 | }, 48 | { 49 | "name": "Watson", 50 | "type": "python", 51 | "request": "launch", 52 | "stopOnEntry": true, 53 | "pythonPath": "${config.python.pythonPath}", 54 | "program": "${workspaceRoot}/console.py", 55 | "args": [ 56 | "dev", 57 | "runserver", 58 | "--noreload=True" 59 | ], 60 | "debugOptions": [ 61 | "WaitOnAbnormalExit", 62 | "WaitOnNormalExit", 63 | "RedirectOutput" 64 | ] 65 | }, 66 | { 67 | "name": "Attach", 68 | "type": "python", 69 | "request": "attach", 70 | "localRoot": "${workspaceRoot}", 71 | "remoteRoot": "${workspaceRoot}", 72 | "port": 3000, 73 | "secret": "my_secret", 74 | "host": "localhost" 75 | } 76 | ] 77 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "python.pythonPath": "/usr/bin/python3.4" 4 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 OpenATC 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ```sh 4 | $ pip install bs4 5 | $ pip install requests 6 | $ pip install urllib3 --upgrade 7 | ``` 8 | 9 | You may also wish to use the included setup script to fill in your info 10 | 11 | ```sh 12 | $ cd Scripts 13 | $ ./makeinfo.py 14 | ``` 15 | 16 | License 17 | ---- 18 | 19 | is licensed under the MIT license. 20 | -------------------------------------------------------------------------------- /Scripts/adidas.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from bs4 import BeautifulSoup as bs 3 | import requests 4 | import timeit 5 | import time 6 | from getconf import * 7 | 8 | # TODO: captcha -- selenium or selenium-requests? 9 | 10 | base_url = 'https://www.adidas.com' 11 | product_id = 'BA8581' 12 | size = '7.5' 13 | 14 | 15 | def sleep(sec): 16 | time.sleep(sec) 17 | 18 | 19 | def add_to_cart(): 20 | response = session.get(base_url + '/us/' + product_id + '.html', headers={'Upgrade-Insecure-Requests': '1'}) 21 | 22 | url = response.url 23 | 24 | soup = bs(response.text, 'html.parser') 25 | 26 | size_container = soup.find('select', {'name': 'pid'}) 27 | 28 | # possible solution to queue 29 | #while size_container is None: 30 | # sleep(.1) 31 | 32 | size_val = 'null' 33 | 34 | # check if sizes are sold out, if not find size value 35 | try: 36 | for values in size_container.find_all('option'): 37 | if size == values.string.strip(): 38 | size_val = values['value'] 39 | break 40 | except: 41 | print('All sold out!') 42 | return False, 'null', 'null' 43 | 44 | payload = { 45 | 'Quantity': '1', 46 | 'ajax': 'true', 47 | 'layer': 'Add To Bag overlay', 48 | 'masterPid': product_id, 49 | 'pid': size_val 50 | } 51 | headers = { 52 | 'Accept': '*/*', 53 | 'Origin': 'http://www.adidas.com', 54 | 'X-Requested-With': 'XMLHttpRequest', 55 | } 56 | 57 | if size_val != 'null': 58 | url = base_url + '/on/demandware.store/Sites-adidas-US-Site/en_US/Cart-MiniAddProduct' 59 | response = session.post(url, data=payload, headers=headers) 60 | if response.status_code == 200: 61 | print('Shoe was added to cart...') 62 | # sleep() 63 | return True, url, size_val 64 | else: 65 | print('{} unavailable'.format(size)) 66 | return False, url, size_val 67 | 68 | 69 | def checkout(): 70 | print('Checking out...') 71 | headers = { 72 | 'Upgrade-Insecure-Requests': '1', 73 | 'Referer': product_url, 74 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' 75 | } 76 | response = session.get(base_url + '/us/delivery-start', headers=headers) 77 | 78 | # sleep() 79 | soup = bs(response.text, 'html.parser') 80 | url = soup.find('div', {'class': 'cart_wrapper rbk_shadow_angle rbk_wrapper_checkout summary_wrapper'})['data-url'] 81 | delivery_key = soup.find('input', {'name': 'dwfrm_delivery_securekey'})['value'] 82 | 83 | # delivery details 84 | headers = { 85 | 'Accept': 'text/html, */*; q=0.01', 86 | 'Origin': 'http://www.adidas.com', 87 | 'X-Requested-With': 'XMLHttpRequest', 88 | 'Referer': 'https://www.adidas.com/us/delivery-start' 89 | } 90 | payload = { 91 | 'dwfrm_cart_selectShippingMethod': 'ShippingMethodID', 92 | 'dwfrm_cart_shippingMethodID_0': 'Standard', 93 | 'dwfrm_delivery_billingOriginalAddress': 'false', 94 | 'dwfrm_delivery_billingSuggestedAddress': 'false', 95 | 'dwfrm_delivery_billing_billingAddress_addressFields_address1': billing_address_1, 96 | 'dwfrm_delivery_billing_billingAddress_addressFields_address2': billing_address_2, 97 | 'dwfrm_delivery_billing_billingAddress_addressFields_city': billing_city, 98 | 'dwfrm_delivery_billing_billingAddress_addressFields_country': billing_country_abbrv, 99 | 'dwfrm_delivery_billing_billingAddress_addressFields_countyProvince': billing_state_abbrv, 100 | 'dwfrm_delivery_billing_billingAddress_addressFields_firstName': first_name, 101 | 'dwfrm_delivery_billing_billingAddress_addressFields_lastName': last_name, 102 | 'dwfrm_delivery_billing_billingAddress_addressFields_phone': phone_number, 103 | 'dwfrm_delivery_billing_billingAddress_addressFields_zip': billing_zip, 104 | 'dwfrm_delivery_billing_billingAddress_isedited': 'false', 105 | 'dwfrm_delivery_savedelivery': 'Review and Pay', 106 | 'dwfrm_delivery_securekey': delivery_key, 107 | 'dwfrm_delivery_shippingOriginalAddress': 'false', 108 | 'dwfrm_delivery_shippingSuggestedAddress': 'false', 109 | 'dwfrm_delivery_singleshipping_shippingAddress_addressFields_address1': shipping_address_1, 110 | 'dwfrm_delivery_singleshipping_shippingAddress_addressFields_address2': shipping_address_2, 111 | 'dwfrm_delivery_singleshipping_shippingAddress_addressFields_city': shipping_city, 112 | 'dwfrm_delivery_singleshipping_shippingAddress_addressFields_countyProvince': shipping_state_abbrv, 113 | 'dwfrm_delivery_singleshipping_shippingAddress_addressFields_firstName': first_name, 114 | 'dwfrm_delivery_singleshipping_shippingAddress_addressFields_lastName': last_name, 115 | 'dwfrm_delivery_singleshipping_shippingAddress_addressFields_phone': phone_number, 116 | 'dwfrm_delivery_singleshipping_shippingAddress_addressFields_zip': shipping_zip, 117 | 'dwfrm_delivery_singleshipping_shippingAddress_ageConfirmation': 'true', 118 | 'dwfrm_delivery_singleshipping_shippingAddress_agreeForSubscription': 'false', 119 | 'dwfrm_delivery_singleshipping_shippingAddress_email_emailAddress': email, 120 | 'dwfrm_delivery_singleshipping_shippingAddress_isedited': 'false', 121 | 'format': 'ajax', 122 | 'referer': 'Cart-Show', 123 | 'shipping-group-0': 'Standard', 124 | 'shippingMethodType_0': 'inline', 125 | 'signup_source': 'shipping', 126 | 'state': shipping_state + ',' 127 | } 128 | 129 | response = session.post(url, data=payload, headers=headers) 130 | 131 | # review & pay 132 | headers = { 133 | 'Accept': 'application/json, text/javascript, */*; q=0.01', 134 | 'Origin': 'https://www.adidas.com', 135 | 'X-Requested-With': 'XMLHttpRequest', 136 | 'Referer': 'https://www.adidas.com/on/demandware.store/Sites-adidas-US-Site/en_US/COSummary-Start' 137 | } 138 | payload = { 139 | 'dwfrm_payment_creditCard_cvn': card_cvv, 140 | 'dwfrm_payment_creditCard_month': card_exp_month, 141 | 'dwfrm_payment_creditCard_number': card_number, 142 | 'dwfrm_payment_creditCard_owner': '{} {}'.format(first_name, last_name), 143 | 'dwfrm_payment_creditCard_type': '001', # visa 144 | 'dwfrm_payment_creditCard_year': card_exp_year, 145 | 'dwfrm_payment_securekey': delivery_key, 146 | 'dwfrm_payment_signcreditcardfields': 'sign' 147 | } 148 | 149 | url = soup.find('form', {'id': 'dwfrm_delivery'})['action'] 150 | response = session.post(url, data=payload, headers=headers) 151 | if response.status_code == 200: 152 | print('Check your email for confirmation!') 153 | 154 | # Main 155 | start = timeit.default_timer() 156 | session = requests.Session() 157 | session.headers.update({ 158 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) ' 159 | 'Chrome/52.0.2743.116 Safari/537.36', 160 | 'DNT': '1', 161 | 'Accept-Encoding': 'gzip, deflate, sdch', 162 | 'Accept-Language': 'en-US,en;q=0.8,da;q=0.6', 163 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' 164 | }) 165 | 166 | successful, product_url, size_val = add_to_cart() 167 | 168 | if successful: 169 | checkout() 170 | 171 | print(timeit.default_timer()-start) 172 | -------------------------------------------------------------------------------- /Scripts/adidas_test.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import urllib 3 | import json 4 | from bs4 import BeautifulSoup as bs 5 | 6 | headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'} 7 | pid = "B27136" 8 | url = "http://www.adidas.com/on/demandware.store/Sites-adidas-US-Site/en_US/Cart-MiniAddProduct?layer=Add%20To%20Bag%20overlay&pid=" + pid + "_650&Quantity=1&masterPid=" + pid + "aq2659add-to-cart-button=" 9 | session = requests.session() 10 | response = session.get(url, headers=headers) 11 | soup = bs(response.text, "html.parser") 12 | print(json.loads(urllib.parse.unquote(soup.find("div", {"class":"hidden"}).getText()))) -------------------------------------------------------------------------------- /Scripts/atclibs.py: -------------------------------------------------------------------------------- 1 | import timeit 2 | 3 | def format_phone(n): 4 | return '({}) {}-{}'.format(n[:3], n[3:6], n[6:]) 5 | 6 | def format_card(n): 7 | return '{} {} {} {}'.format(n[:4], n[4:8], n[8:12], n[12:]) 8 | 9 | def tick(): 10 | global tick 11 | tick = timeit.default_timer() 12 | return tick 13 | 14 | def tock(): 15 | tock = timeit.default_timer() 16 | print(tock - tick) 17 | return tock 18 | 19 | def footsites_parse_size(size): 20 | size_ = size 21 | 22 | if size[-2:] != ".5": 23 | size_ = size + '.0' 24 | 25 | if float(size) < 10: 26 | size_ = '0' + size 27 | 28 | return (size_) -------------------------------------------------------------------------------- /Scripts/bodega.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | import re 4 | import requests 5 | import timeit 6 | from bs4 import BeautifulSoup as bs 7 | from getconf import * 8 | 9 | # User input 10 | use_early_link = True 11 | base_url = 'http://shop.bdgastore.com' 12 | early_link = base_url + '/collections/footwear/products/nike-tennis-classic-ultra-flyknit-5' 13 | shoe_size = '8' 14 | 15 | session = requests.Session() 16 | 17 | def get_shoe_product_payload(soup): 18 | """Accepts soup of the product page, returns payload for proper size""" 19 | 20 | product_options = soup.select('#product-select option') 21 | product_id = None 22 | for product in product_options: 23 | if ' {} '.format(shoe_size) in product.text: # format so doesn't detect size in price 24 | product_id = product['value'] 25 | print(product_id) 26 | break 27 | 28 | if product_id: 29 | bot_key_elem = soup.select('#key')[0] 30 | bot_key = bot_key_elem['value'] 31 | 32 | print(bot_key) 33 | else: 34 | print('Could not find correct size, may be sold out') 35 | quit() 36 | 37 | payload = { 38 | 'id': product_id, 39 | 'properties[bot - key]': bot_key 40 | } 41 | 42 | return payload 43 | 44 | 45 | def add_to_cart(early_link, shoe_size): # TODO: support for products other than shoes 46 | 47 | print('adding to cart') 48 | response = session.get(early_link) 49 | content = response.content 50 | soup = bs(content, 'html.parser') 51 | payload = get_shoe_product_payload(soup) 52 | 53 | response = session.post(base_url + '/cart/add.js', data=payload) 54 | response.raise_for_status() 55 | 56 | # Confirms item added to cart, can comment out to speed up script 57 | cart = session.get(base_url + '/cart') 58 | soup = bs(cart.content, 'html.parser') 59 | cart_count = soup.find('span', 'cartcount').text 60 | print('{} item added to cart'.format(cart_count)) 61 | 62 | 63 | def check_out(): 64 | 65 | print('checking out') 66 | cart_url = 'http://shop.bdgastore.com/checkout' 67 | response = session.get(cart_url) 68 | soup = bs(response.content, 'html.parser') 69 | form = soup.find('form', {'action': re.compile('(?<=shop.bdgastore.com)(.*)(?=/checkouts/)')}) 70 | print('submitting contact info') 71 | 72 | 73 | # Contact Info 74 | payload = { 75 | 'utf8': '✓', 76 | '_method': 'patch', 77 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 78 | 'previous_step': 'contact_information', 79 | 'checkout[email]': email, 80 | 'checkout[shipping_address][first_name]': first_name, 81 | 'checkout[shipping_address][last_name]': last_name, 82 | 'checkout[shipping_address][company]': '', 83 | 'checkout[shipping_address][address1]': shipping_address_1, 84 | 'checkout[shipping_address][address2]': shipping_apt_suite, 85 | 'checkout[shipping_address][city]': shipping_city, 86 | 'checkout[shipping_address][country]': 'United States', 87 | 'checkout[shipping_address][province]': '', 88 | 'checkout[shipping_address][province]': '', 89 | 'checkout[shipping_address][province]': shipping_state, 90 | 'checkout[shipping_address][zip]': shipping_zip, 91 | 'checkout[shipping_address][phone]': phone_number, 92 | 'remember_me': 'false', 93 | 'step': 'shipping_method', 94 | } 95 | response = session.post(form['action'], data=payload) 96 | assert('step=shipping_method' in response.url) 97 | 98 | 99 | # Shipping Method 100 | soup = bs(response.text, 'html.parser') 101 | form = soup.find('form', {'action': re.compile('(?<=shop.bdgastore.com)(.*)(?=/checkouts/)')}) 102 | print('Submitting shipping info') 103 | 104 | #TODO: Determine how to submit desired shipping_rate, uses default now 105 | payload = { 106 | 'utf8': '✓', 107 | '_method': 'patch', 108 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 109 | 'previous_step': 'shipping_method', 110 | 'step': 'payment_method', 111 | # 'checkout[shipping_rate][id]': 'shopify -$50.01 - 100 - 9.00' 112 | } 113 | 114 | response = session.post(form['action'], data=payload) 115 | assert('step=payment' in response.url) 116 | 117 | #Payment Information 118 | soup = bs(response.text, 'html.parser') 119 | form = soup.find('form', {'action': re.compile('deposit')}) 120 | print('submitting payment info') 121 | 122 | payload = { 123 | 'utf8': '✓', 124 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 125 | 'previous_step': 'payment_method', 126 | 'step': '', 127 | 's': '', 128 | 'c': form.find('input', {'name': 'c'})['value'], 129 | 'd': form.find('input', {'name': 'd'})['value'], 130 | 'checkout[payment_gateway]': form.find('input', {'name': 'checkout[payment_gateway]'})['value'], 131 | 'checkout[credit_card][number]': card_number, 132 | 'checkout[credit_card][name]': first_name + ' ' + last_name, 133 | 'checkout[credit_card][month]': card_exp_month.strip('0'), 134 | 'checkout[credit_card][year]': card_exp_year, 135 | 'expiry': card_exp_month + ' / ' + card_exp_year[-2:], 136 | 'checkout[credit_card][verification_value]': card_cvv, 137 | 'checkout[different_billing_address]': 'false', 138 | 'checkout[buyer_accepts_marketing]': '0', 139 | 'complete': '1', 140 | 'checkout[client_details][browser_width]': '665', 141 | 'checkout[client_details][browser_height]': '705', 142 | 'checkout[client_details][javascript_enabled]': '1' 143 | } 144 | 145 | response = session.post(form['action'], data=payload) # TODO: not tested with real cvv, but form submission seems to work 146 | 147 | print('Checkout complete. Please view the following page to confirm') 148 | print(response.url) 149 | 150 | 151 | 152 | start = timeit.default_timer() 153 | add_to_cart(early_link, 10.5) 154 | check_out() 155 | stop = timeit.default_timer() 156 | print('{} seconds'.format(stop - start)) 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /Scripts/caliroots.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import requests 3 | import re 4 | import timeit 5 | import json 6 | from bs4 import BeautifulSoup as bs 7 | from getconf import * 8 | 9 | # User input 10 | size = '6.5' 11 | use_early_link = True 12 | early_link = 'https://caliroots.com/adidas-originals-tubular-nova-primeknit-s74917/p/53784' 13 | 14 | def checkout(): # USA checkout 15 | # TODO: Get rid of this by making a list of state codes 16 | response = session.get('https://caliroots.com/express/checkout/49') 17 | soup = bs(response.text, 'html.parser') 18 | scripts = soup.findAll('script') 19 | for script in scripts: 20 | if 'window.meta = ' in script.getText(): 21 | regex = re.compile('window\.meta = ((.|\n)*?);') 22 | match = regex.search(script.getText()) 23 | meta = json.loads(match.groups()[0]) 24 | print (soup) 25 | 26 | print (meta) 27 | payload = { 28 | 'ctx.COUNTRY' : 'GB', 29 | 'meta' : { 30 | 'token' : meta.token, 31 | 'calc' : meta.calc, 32 | 'csci' : meta.csci, 33 | 'locale' : meta.locality, 34 | 'state' : 'ui_checkout_login', 35 | 'app_name' : 'hermesnodeweb' 36 | } 37 | } 38 | response = session.get('https://www.paypal.com/webapps/hermes/api/pxp/xo_aries_hermes_guest_throttle', data=payload) 39 | print (response.text) 40 | # Main 41 | start = timeit.default_timer() 42 | 43 | session = requests.session() 44 | 45 | if use_early_link: 46 | response = session.get(early_link) 47 | soup = bs(response.text, 'html.parser') 48 | 49 | options = soup.find_all('option') 50 | regexp = re.compile(size.replace('.', ',')) 51 | product_id = '' 52 | 53 | for option in options: 54 | if regexp.search(option.getText()) is not None: 55 | product_id = option['value'] 56 | continue 57 | 58 | payload = { 59 | 'id' : product_id, 60 | 'partial' : 'ajax-cart' 61 | } 62 | 63 | response = session.post('https://caliroots.com/cart/add', data=payload) 64 | soup = bs(response.text, 'html.parser') 65 | checkout() 66 | 67 | stop = timeit.default_timer() 68 | print (stop - start) 69 | -------------------------------------------------------------------------------- /Scripts/checkstock.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Basic stock checker by making manual searches for a product (NMD in this case) 3 | # Need to update this to be more general 4 | 5 | import requests 6 | import re 7 | import json 8 | import time 9 | from bs4 import BeautifulSoup as bs 10 | 11 | query = "nmd" 12 | 13 | def einhalb(): 14 | print ('43einhalb...') 15 | response = session.get('http://www.43einhalb.com/en/search?searchstring=' + query) 16 | soup = bs(response.text, 'html.parser') 17 | productListing = soup.find('ul', {'class' : 'productListing'}) 18 | items = productListing.findAll('li', {'class' : 'item'}) 19 | for item in items: 20 | variantListing = item.find('ul', {'class' : 'availableVariants'}) 21 | links = variantListing.findAll('li', {'title' : ''}) 22 | for link in links: 23 | printToSheet(item.find('span', {'class' : 'productName'}).getText(), 'http://www.43einhalb.com' + link.find('a')['href']) 24 | 25 | def overkill(): 26 | print ('Overkill...') 27 | response = session.get('https://www.overkillshop.com/en/catalogsearch/result/?q=' + query) 28 | soup = bs(response.text, 'html.parser') 29 | productListing = soup.find('ul', {'class' : 'products-grid'}) 30 | if not productListing is None: 31 | items = productListing.findAll('li', {'class' : 'item'}) 32 | for item in items: 33 | variantListing = item.find('ul', {'class' : 'text-left'}) 34 | if not variantListing is None: 35 | links = variantListing.findAll('a', {'label_show' : ''}) 36 | for link in links: 37 | if 'disabled' not in link.attrs['class']: 38 | printToSheet(item.find('a', {'class' : 'product-name'})['title'], link['href']) 39 | 40 | def sns(): 41 | print ('Sneakersnstuff...') 42 | response = session.get('http://www.jdsports.co.uk/search/' + query + '/') 43 | soup = bs(response.text, 'html.parser') 44 | items = soup.findAll('li', {'class' : 'product'}) 45 | for item in items: 46 | desc = item.find('p') 47 | if desc.getText() != 'Sold out': 48 | printToSheet(item.find('a', {'class' : 'plink name'}), 'http://www.sneakersnstuff.com' + item.find('a')['href']) 49 | 50 | def oneblockdown(): 51 | print ('One Block Down...') 52 | response = session.get('http://www.oneblockdown.it/en/search/' + query) 53 | soup = bs(response.text, 'html.parser') 54 | scripts = soup.findAll('script') 55 | for script in scripts: 56 | if 'preloadedItems' in script.getText(): 57 | regex = re.compile('var preloadedItems = (.*?);') 58 | preloadedItems = regex.search(script.getText()) 59 | items = json.loads(preloadedItems.groups()[0]) 60 | for item in items: 61 | if item['stock'] != []: 62 | link = 'http://www.oneblockdown.it/en/footwear-lifestyle/' + item['stock'][0]['itemId'] 63 | printToSheet(item['alias'], link) 64 | 65 | def offspring(): 66 | print ('Offspring...') 67 | response = session.get('http://www.offspring.co.uk/view/search?search=' + query) 68 | soup = bs(response.text, 'html.parser') 69 | items = soup.findAll('div', {'class' : 'productList_item'}) 70 | for item in items: 71 | productCode = item.find('div', {'class' : 'containerTitle productList_quickbuy'}) 72 | payload = { 73 | 'productCode' : productCode['data-productcode'], 74 | 'og' : 'false' 75 | } 76 | response = session.post('http://www.offspring.co.uk/view/basket/viewSizes', data=payload) 77 | responseJson = json.loads(response.text) 78 | if responseJson['variantOptions']['hasStock']: 79 | printToSheet(responseJson['shortDescription'] + ' ' + responseJson['shoeColour']['name'], 'http://www.offspring.co.uk' + item.find('a')['href']) 80 | 81 | def titolo(): 82 | print ('Titolo...') 83 | response = session.get('https://en.titoloshop.com/catalogsearch/result/?q=' + query) 84 | soup = bs(response.text, 'html.parser') 85 | items = soup.findAll('li', {'class' : 'item'}) 86 | for item in items: 87 | if item.find('p') is None or 'out-of-stock' not in item.find('p').attrs['class']: 88 | printToSheet(item.find('span', {'class' : 'name'}).getText(), item.find('a')['href']) 89 | 90 | def solebox(): 91 | print ('Solebox...') 92 | response = session.get('https://www.solebox.com/catalogsearch/result/?q=' + query) 93 | soup = bs(response.text, 'html.parser') 94 | items = soup.findAll('li', {'class' : 'product-grid-item'}) 95 | for item in items: 96 | if query in item.find('h2').getText() and item.find('div', {'class' : 'value'}) is None: 97 | printToSheet(item.find('a')['title'], item.find('a')['href']) 98 | 99 | def endclothing(): 100 | print ('end Clothing...') 101 | response = session.get('http://www.endclothing.com/gb/catalogsearch/result/?q=' + query) 102 | soup = bs(response.text, 'html.parser') 103 | print (soup) 104 | items = soup.findAll('div', {'class' : 'thumbnail item'}) 105 | print(items) 106 | for item in items: 107 | response = session.get(item['href']) 108 | soup = bs(response.text, 'html.parser') 109 | holder = soup.find('div', {'class' : 'add-to-holder'}) 110 | print(holder) 111 | if holder is None: 112 | description = soup.find('div', {'class' : 'product-shop product-description'}) 113 | printToSheet(description.find('h1').getText() + ' ' + description.find('h3').getText(), item['href']) 114 | 115 | def jdsports(): 116 | print ('JDSports...') 117 | response = session.get('http://www.jdsports.co.uk/search/' + query + '/') 118 | soup = bs(response.text, 'html.parser') 119 | items = soup.findAll('li', {'class' : 'listItem'}) 120 | for item in items: 121 | link = 'http://www.jdsports.co.uk' + item.find('a')['href'] 122 | response = session.get(link + 'quickview') 123 | soup = bs(response.text, 'html.parser') 124 | availability = soup.find('link', {'itemprop' : 'availability'}) 125 | if availability is not None and availability['href'] == 'http://schema.org/InStock': 126 | regex = re.compile('\/product\/(.*?)\/') 127 | match = regex.search(link).groups()[0].replace('-',' ').title() 128 | printToSheet(match, link) 129 | 130 | def zolando(): 131 | print ('Zolando...') 132 | response = session.get('https://www.zalando.co.uk/catalog/?q=' + query + '&qf=1') 133 | soup = bs(response.text, 'html.parser') 134 | items = soup.findAll('li', {'class' : 'catalogArticlesList_item'}) 135 | for item in items: 136 | if item['data-s'] != '': 137 | printToSheet(item.find('div', {'class' : 'catalogArticlesList_articleName'}).getText().replace(' - Trainers -', ''), 'https://www.zalando.co.uk' + item.find('a')['href']) 138 | 139 | def bluetomato(): 140 | print ('Blue Tomato...') 141 | response = session.get('https://www.blue-tomato.com/en-GB/page/adidas-originals-' + query + '/') 142 | soup = bs(response.text, 'html.parser') 143 | items = soup.findAll('li', {'class' : 'productcell'}) 144 | for item in items: 145 | link = 'https://www.blue-tomato.com' + item['data-href'] 146 | response = session.get(link) 147 | soup = bs(response.text, 'html.parser') 148 | availability = soup.find('li', {'class' : 'active'}) 149 | if availability is not None: 150 | printToSheet(item.find('p').getText().title(), link) 151 | 152 | def caliroots(): 153 | print ('Caliroots...') 154 | response = session.get('https://caliroots.com/search/searchbytext?key=' + query) 155 | soup = bs(response.text, 'html.parser') 156 | items = soup.findAll('li', {'class' : 'product'}) 157 | for item in items: 158 | availability = soup.find('div', {'class' : 'sold-out'}) 159 | if availability is None: 160 | printToSheet(item.find('p', {'class' : 'name'}).getText(), 'https://caliroots.com' + item.find('a')['href']) 161 | 162 | def eastbay(): 163 | print ('Eastbay...') 164 | response = session.get('http://www.eastbay.com/Shoes/_-_/N-ne/keyword-' + query + '?cm_REF=Shoes&Nr=AND%28P_RecordType%3AProduct%29') 165 | soup = bs(response.text, 'html.parser') 166 | items = soup.findAll('li') 167 | for item in items: 168 | if item.has_attr('data-sku'): 169 | response = session.get('http://www.eastbay.com/search/json.cfm?Rpp=1&Ntt=' + item['data-sku']) 170 | loadedJSON = json.loads(response.text)['RECORDS'] 171 | if len(loadedJSON) > 0 and loadedJSON[0]['PROPERTIES']['P_IsSaleable'] == 'Y': 172 | printToSheet(item.find('span', {'class' : 'product_title'}).getText() + ' ' + str(loadedJSON[0]['DIMENSIONS']['Color']).replace('[','').replace(']','').replace("'",'').replace(', ','/'), item.find('a')['href']) 173 | 174 | def nakedcph(): 175 | print ('Naked CPH...') 176 | response = session.get('http://www.nakedcph.com/catalog?search=' + query) 177 | soup = bs(response.text, 'html.parser') 178 | items_list = soup.find('ul', {'class' : 'list-commodity list-commodity-grid'}) 179 | items = items_list.findAll('li') 180 | for item in items: 181 | response = session.get(item.find('a')['href']) 182 | soup = bs(response.text, 'html.parser') 183 | availability = soup.find('div', {'id' : 'commodity-show-outofstock'}) 184 | if availability is None: 185 | printToSheet(item.find('span', {'class' : 'list-commodity-title'}).getText(), item.find('a')['href']) 186 | 187 | def snipes(): 188 | print ('Snipes...') 189 | response = session.get('https://www.snipes.com/search.html?q=' + query + '&submit=Finden') 190 | soup = bs(response.text, 'html.parser') 191 | items = soup.findAll('dl', {'class' : 'm_product_thumb'}) 192 | for item in items: 193 | pattern = re.compile('(.*?);jsessionid') 194 | match = pattern.search(item.findAll('a')[1]['href']) 195 | if match is None: 196 | pattern = re.compile('(.*?)\?r') 197 | match = pattern.search(item.findAll('a')[1]['href']) 198 | printToSheet(''.join(item.findAll('a')[1].getText().split()), 'https://www.snipes.com' + match.groups()[0]) 199 | 200 | def asphaltgold(): 201 | print ('Asphalt Gold...') 202 | response = session.get('https://asphaltgold.de/de/catalogsearch/result/?q=' + query) 203 | soup = bs(response.text, 'html.parser') 204 | items = soup.findAll('section', {'class' : 'item'}) 205 | for item in items: 206 | response = session.get(item.findAll('a')[1]['href']) 207 | soup = bs(response.text, 'html.parser') 208 | availability = soup.find('button', {'class' : 'btn-cart'}) 209 | countdown = soup.find('div', {'id' : 'productrelease_countdown'}) 210 | if not countdown is None or not availability is None or not 'Derzeit nicht' in availability.getText(): 211 | printToSheet(item.findAll('a')[1].getText(), item.find('a')['href']) 212 | 213 | def baskets(): 214 | print ('Baskets...') 215 | response = session.get('http://www.baskets-store.com/catalogsearch/result/?q=' + query) 216 | soup = bs(response.text, 'html.parser') 217 | items = soup.findAll('div', {'class' : 'item'}) 218 | for item in items: 219 | options = soup.find('ul', {'class' : 'option'}) 220 | availability = soup.findAll('li', {'class' : 'option'}) 221 | is_avail = False 222 | for option in availability: 223 | if not 'disabled' in option.attrs['class']: 224 | is_avail = True 225 | 226 | if is_avail == True: 227 | printToSheet(item.find('a')['title'], item.find('a')['href']) 228 | 229 | def bertola(): 230 | print ('Bertola...') 231 | response = session.get('http://www.bertolashop.com/storeonline/gb/ricerca?controller=search&orderby=position&orderway=desc&search_query=' + query + '&submit_search=') 232 | soup = bs(response.text, 'html.parser') 233 | items = soup.findAll('li', {'class' : 'ajax_block_product'}) 234 | for item in items: 235 | availability = item.find('span', {'class' : 'available-dif'}) 236 | if 'Product available' in availability.getText(): 237 | printToSheet(item.find('a')['title'], item.find('a')['href']) 238 | 239 | def asos(): 240 | print ('ASOS...') 241 | response = session.get('http://www.asos.com/search/' + query + '?q=' + query) 242 | soup = bs(response.text, 'html.parser') 243 | item = soup.find('a', {'class' : 'add-to-bag'}) 244 | if not item is None: 245 | printToSheet(soup.find('title').getText(), soup.find('link', {'rel' : 'alternate'})['href']) 246 | 247 | 248 | def printToSheet(title, link): 249 | print (link) 250 | 251 | session = requests.session() 252 | 253 | sites = [asos, bertola, baskets, asphaltgold, einhalb, overkill, sns, 254 | oneblockdown, offspring, titolo, solebox, jdsports, zolando, 255 | bluetomato, caliroots, eastbay, snipes] 256 | while True: 257 | for x in range(0, len(sites)): 258 | try: 259 | sites[x]() 260 | except Exception: 261 | print ('ERROR') 262 | pass 263 | 264 | print ('') 265 | time.sleep(60) 266 | -------------------------------------------------------------------------------- /Scripts/footlocker.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import requests 3 | import re 4 | import timeit 5 | import json 6 | from multiprocessing.dummy import Pool as ThreadPool 7 | from bs4 import BeautifulSoup as bs 8 | from getconf import * 9 | from atclibs import * 10 | from selenium import webdriver 11 | 12 | """ 13 | NOTE: 14 | billAddressType changes from 'different' to 'new' possibly depending on if shipping/bill address is the same 15 | """ 16 | 17 | base_url = 'http://www.footlocker.com' 18 | 19 | # User input 20 | use_early_link = True 21 | early_link = "http://www.footlocker.com/product/model:175563/sku:11881010/nike-roshe-one-mens/black/grey/?cm=" 22 | use_keyword = False 23 | size = "6.5" 24 | size = footsites_parse_size(size) 25 | 26 | def add_to_cart(url): 27 | response = session.get(url) 28 | soup = bs(response.text, 'html.parser') 29 | referer = response.url 30 | 31 | sku = soup.find('input', {'id': 'pdp_selectedSKU'})['value'] 32 | model_num = soup.find('input', {'id': 'pdp_model'})['value'] 33 | request_key = soup.find('input', {'id': 'requestKey'})['value'] 34 | 35 | payload = { 36 | 'BV_TrackingTag_QA_Display_Sort': '', 37 | 'BV_TrackingTag_Review_Display_Sort': 'http://footlocker.ugc.bazaarvoice.com/8001/' + sku + '/reviews.djs?format=embeddedhtml', 38 | 'coreMetricsCategory': 'blank', 39 | 'fulfillmentType': 'SHIP_TO_HOME', 40 | 'hasXYPromo': 'false', 41 | 'inlineAddToCart': '0,1', 42 | 'qty': '1', 43 | 'rdo_deliveryMethod': 'shiptohome', 44 | 'requestKey': request_key, 45 | 'size': size, 46 | 'sku': sku, 47 | 'storeCostOfGoods': '0.00', 48 | 'storeNumber': '00000', 49 | 'the_model_nbr': model_num 50 | } 51 | headers = { 52 | 'Accept': '*/*', 53 | 'Origin': base_url, 54 | 'X-Requested-With': 'XMLHttpRequest', 55 | 'Referer': referer, 56 | 'Accept-Encoding': 'gzip, deflate', 57 | } 58 | 59 | response = session.post(base_url + '/catalog/miniAddToCart.cfm?secure=0&', headers=headers, data=payload) 60 | soup = bs(response.text, 'html.parser') 61 | error = soup.find('span', {'class' : 'error'}) 62 | 63 | return (error is None) 64 | 65 | def checkout(): 66 | cookies = session.cookies.get_dict() 67 | 68 | for i in cookies: 69 | driver.execute_script("document.cookie = \"" + i + "=" + cookies[i] + ";path=/;domain=.footlocker.com\""); 70 | 71 | driver.get('http://www.footlocker.com/shoppingcart/?sessionExpired=true') 72 | driver.execute_script("inventoryCheck_panel.open();") 73 | 74 | response = session.get('https://www.footlocker.com/checkout/?uri=checkout') 75 | soup = bs(response.text, 'html.parser') 76 | 77 | device_id = soup.find('input', {'id': 'bb_device_id'})['value'] 78 | hbg = soup.find('input', {'id': 'hbg'})['value'] 79 | TID = soup.find('form', {'id': 'emailVerificationForm'})['action'] 80 | request_key = soup.find('input', {'id': 'requestKey'})['value'] 81 | 82 | payload = { 83 | 'CPCOrSourceCode':'', 84 | 'CardCCV':card_cvv, 85 | 'CardExpireDateMM':card_exp_month, 86 | 'CardExpireDateYY':card_exp_year, 87 | 'CardNumber':card_number, 88 | 'addressBookEnabled': 'true', 89 | 'bb_device_id': device_id, 90 | 'bdday': '01', 91 | 'bdmonth': '01', 92 | 'bdyear': '1900', 93 | 'billAPOFPOCountry': 'US', 94 | 'billAPOFPOPostalCode':'', 95 | 'billAPOFPORegion':'', 96 | 'billAPOFPOState':'', 97 | 'billAddress1': shipping_address_1, 98 | 'billAddress2':shipping_address_2, 99 | 'billAddressInputType': 'single', 100 | 'billAddressType': 'new', 101 | 'billCity': shipping_city, 102 | 'billConfirmEmail': email, 103 | 'billCountry': 'US', 104 | 'billEmailAddress':email, 105 | 'billFirstName': first_name, 106 | 'billHomePhone': phone_number, 107 | 'billLastName': last_name, 108 | 'billMeLaterStage': 'NotInitialized', 109 | 'billMobilePhone':'', 110 | 'billMyAddressBookIndex': '-1', 111 | 'billPaneShipToBillingAddress': 'true', 112 | 'billPostalCode': shipping_zip, 113 | 'billProvince':'', 114 | 'billState': shipping_state, 115 | 'bmlConsent': 'Yes', 116 | 'fieldCount': '1', 117 | 'giftCardCode_1':'', 118 | 'giftCardPin_1':'', 119 | 'hbg': hbg, 120 | 'loginHeaderEmailAddress': email, 121 | 'loginHeaderPassword': '', 122 | 'loginPaneConfirmNewEmailAddress':'', 123 | 'loginPaneEmailAddress':'', 124 | 'loginPaneNewEmailAddress':'', 125 | 'loginPanePassword':'', 126 | 'orderReviewPaneBillSubscribeEmail': 'true', 127 | 'payMethodPaneCVV':'', 128 | 'payMethodPaneCardNumber':'', 129 | 'payMethodPaneCardType':'', 130 | 'payMethodPaneConfirmCardNumber':'', 131 | 'payMethodPaneExpireMonth':'', 132 | 'payMethodPaneExpireYear':'', 133 | 'payMethodPaneStoredCCCVV':'', 134 | 'payMethodPaneStoredCCExpireMonth':'', 135 | 'payMethodPaneStoredCCExpireYear':'', 136 | 'payMethodPaneStoredType':'', 137 | 'promoType':'', 138 | 'requestKey': request_key, 139 | 'shipAPOFPOCountry': 'US', 140 | 'shipAPOFPOPostalCode':'', 141 | 'shipAPOFPORegion':'', 142 | 'shipAPOFPOState':'', 143 | 'shipAddress1':'', 144 | 'shipAddress2':'', 145 | 'shipAddressInputType': 'single', 146 | 'shipAddressType': 'different', 147 | 'shipCity':'', 148 | 'shipCountry': 'US', 149 | 'shipFirstName':'', 150 | 'shipHomePhone':'', 151 | 'shipLastName':'', 152 | 'shipMethodCodeS2S':'', 153 | 'shipMyAddressBookIndex': '-1', 154 | 'shipPostalCode':'', 155 | 'shipProvince':'', 156 | 'shipState':'', 157 | 'shipToStore': 'false', 158 | 'ssn': '1000', 159 | 'storePickupInputPostalCode':'', 160 | 'verifiedCheckoutData': { 161 | 'maxVisitedPane': 'billAddressPane', 162 | 'updateBillingForBML': 'false', 163 | 'billMyAddressBookIndex': '-1', 164 | 'addressNeedsVerification': 'true', 165 | 'billFirstName': first_name, 166 | 'billLastName': last_name, 167 | 'billAddress1': shipping_address_1, 168 | 'billAddress2': shipping_address_1, 169 | 'billCity': shipping_city, 170 | 'billState': shipping_state, 171 | 'billProvince': '', 172 | 'billPostalCode': '', 173 | 'billHomePhone': '', 174 | 'billMobilePhone': '', 175 | 'billCountry': 'US', 176 | 'billEmailAddress': email, 177 | 'billConfirmEmail': email, 178 | 'billAddrIsPhysical': 'true', 179 | 'billSubscribePhone': 'false', 180 | 'billAbbreviatedAddress': 'false', 181 | 'shipUpdateDefaultAddress': 'false', 182 | 'VIPNumber': '', 183 | 'accountBillAddress': {'billMyAddressBookIndex': '-1'}, 'selectedBillAddress': {}, 184 | 'billMyAddressBook': [] 185 | } 186 | } 187 | print(payload) 188 | # response = session.post(url, data=payload, headers=headers) 189 | 190 | 191 | # Main 192 | 193 | tick() 194 | 195 | global response 196 | 197 | driver = webdriver.Firefox() 198 | driver.get(base_url) 199 | driver.delete_all_cookies() 200 | 201 | session = requests.Session() 202 | session.headers.update({ 203 | 'User-Agent': '"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0"', 204 | 'DNT': '1', 205 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 206 | 'Accept-Encoding': 'gzip, deflate, sdch', 207 | 'Accept-Language': 'en-US,en;q=0.8,da;q=0.6', 208 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' 209 | }) 210 | 211 | url = "" 212 | 213 | if use_early_link: 214 | url = early_link 215 | else: 216 | url = base_url + '/product/sku:{}/'.format(product_id) 217 | 218 | if add_to_cart(url): 219 | print('CHECKOUT') 220 | checkout() 221 | 222 | tock() 223 | -------------------------------------------------------------------------------- /Scripts/getconf.py: -------------------------------------------------------------------------------- 1 | import json 2 | with open("userinfo.json") as conffile: 3 | userinfo = json.load(conffile) 4 | 5 | # No real better way... 6 | card_cvv = userinfo["card_cvv"] 7 | card_exp_month = userinfo["card_exp_month"] 8 | card_exp_year = userinfo["card_exp_year"] 9 | card_number = userinfo["card_number"] 10 | card_type = userinfo["card_type"] 11 | email = userinfo["email"] 12 | first_name = userinfo["first_name"] 13 | last_name = userinfo["last_name"] 14 | phone_number = userinfo["phone_number"] 15 | shipping_address_1 = userinfo["shipping_address_1"] 16 | shipping_address_2 = userinfo["shipping_address_2"] 17 | shipping_apt_suite = userinfo["shipping_apt_suite"] 18 | shipping_city = userinfo["shipping_city"] 19 | shipping_state = userinfo["shipping_state"] 20 | shipping_state_abbrv = userinfo["shipping_state_abbrv"] 21 | shipping_zip = userinfo["shipping_zip"] 22 | shipping_country = userinfo["shipping_country"] 23 | shipping_country_abbrv = userinfo["shipping_country_abbrv"] 24 | billing_address_1 = userinfo["billing_address_1"] 25 | billing_address_2 = userinfo["billing_address_2"] 26 | billing_apt_suite = userinfo["billing_apt_suite"] 27 | billing_city = userinfo["billing_city"] 28 | billing_state = userinfo["billing_state"] 29 | billing_state_abbrv = userinfo["billing_state_abbrv"] 30 | billing_zip = userinfo["billing_zip"] 31 | billing_country = userinfo["billing_country"] 32 | billing_country_abbrv = userinfo["billing_country_abbrv"] 33 | 34 | 35 | -------------------------------------------------------------------------------- /Scripts/ghostdriver.log: -------------------------------------------------------------------------------- 1 | [INFO - 2016-09-02T16:49:15.510Z] GhostDriver - Main - running on port 48538 2 | [INFO - 2016-09-02T16:49:16.371Z] Session [2f600df0-712d-11e6-8d57-2173e2272414] - page.settings - {"XSSAuditingEnabled":false,"javascriptCanCloseWindows":true,"javascriptCanOpenWindows":true,"javascriptEnabled":true,"loadImages":true,"localToRemoteUrlAccessEnabled":false,"userAgent":"Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.1.1 Safari/538.1","webSecurityEnabled":true} 3 | [INFO - 2016-09-02T16:49:16.371Z] Session [2f600df0-712d-11e6-8d57-2173e2272414] - page.customHeaders: - {} 4 | [INFO - 2016-09-02T16:49:16.371Z] Session [2f600df0-712d-11e6-8d57-2173e2272414] - Session.negotiatedCapabilities - {"browserName":"phantomjs","version":"2.1.1","driverName":"ghostdriver","driverVersion":"1.2.0","platform":"linux-unknown-64bit","javascriptEnabled":true,"takesScreenshot":true,"handlesAlerts":false,"databaseEnabled":false,"locationContextEnabled":false,"applicationCacheEnabled":false,"browserConnectionEnabled":false,"cssSelectorsEnabled":true,"webStorageEnabled":false,"rotatable":false,"acceptSslCerts":false,"nativeEvents":true,"proxy":{"proxyType":"direct"}} 5 | [INFO - 2016-09-02T16:49:16.371Z] SessionManagerReqHand - _postNewSessionCommand - New Session Created: 2f600df0-712d-11e6-8d57-2173e2272414 6 | [INFO - 2016-09-02T16:54:15.509Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 7 | [INFO - 2016-09-02T16:59:15.509Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 8 | [INFO - 2016-09-02T17:01:51.222Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 9 | [INFO - 2016-09-02T17:02:03.071Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 10 | [INFO - 2016-09-02T17:01:32.758Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 11 | [INFO - 2016-09-02T17:00:27.316Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 12 | [INFO - 2016-09-02T16:59:41.163Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 13 | [INFO - 2016-09-02T17:01:07.361Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 14 | [INFO - 2016-09-02T16:52:06.929Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 15 | [INFO - 2016-09-02T16:57:06.929Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 16 | [INFO - 2016-09-02T17:02:06.929Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 17 | [INFO - 2016-09-02T17:03:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 18 | [INFO - 2016-09-02T17:08:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 19 | [INFO - 2016-09-02T17:13:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 20 | [INFO - 2016-09-02T17:18:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 21 | [INFO - 2016-09-02T17:23:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 22 | [INFO - 2016-09-02T17:28:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 23 | [INFO - 2016-09-02T17:33:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 24 | [INFO - 2016-09-02T17:38:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 25 | [INFO - 2016-09-02T17:43:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 26 | [INFO - 2016-09-02T17:48:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 27 | [INFO - 2016-09-02T17:53:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 28 | [INFO - 2016-09-02T17:58:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 29 | [INFO - 2016-09-02T18:03:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 30 | [INFO - 2016-09-02T18:08:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 31 | [INFO - 2016-09-02T18:13:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 32 | [INFO - 2016-09-02T18:18:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 33 | [INFO - 2016-09-02T18:23:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 34 | [INFO - 2016-09-02T18:28:40.162Z] SessionManagerReqHand - _cleanupWindowlessSessions - Asynchronous Sessions clean-up phase starting NOW 35 | -------------------------------------------------------------------------------- /Scripts/jimmyjazz.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import requests 3 | import timeit 4 | from bs4 import BeautifulSoup as bs 5 | import time 6 | from getconf import * 7 | 8 | # User input 9 | use_early_link = True 10 | early_link = '' 11 | use_keyword = False 12 | shoe_size = '' 13 | 14 | 15 | # Functions 16 | def add_to_cart(early_link, shoe_size): 17 | print('Adding to Cart') 18 | response = session.get(early_link, headers=headers) 19 | soup = bs(response.text, 'html.parser') 20 | 21 | available_sizes = [] 22 | size_ids = [] 23 | size_box = soup.find_all('a', {'class': 'box'}) 24 | 25 | for a in size_box: 26 | for sizes in a.stripped_strings: 27 | available_sizes.append(sizes) 28 | for ids in size_box: 29 | size_ids.append(ids['id'][-8:]) 30 | 31 | if shoe_size in available_sizes: 32 | pos = available_sizes.index(shoe_size) 33 | id = size_ids[pos] 34 | response = session.get('http://www.jimmyjazz.com/cart-request/cart/add/' + id + '/1', headers=headers) 35 | time.sleep(.5) 36 | return 1 37 | else: 38 | return 0 39 | 40 | 41 | def checkout(): 42 | print('Checking Out') 43 | response = session.get('http://www.jimmyjazz.com/cart', headers=headers) 44 | 45 | response = session.get('https://www.jimmyjazz.com/cart/checkout', headers=headers) 46 | soup = bs(response.text, 'html.parser') 47 | form_id = soup.find('input', {'name': 'form_build_id'})['id'] 48 | 49 | payload = { 50 | 'billing_address1': billing_address_1, 51 | 'billing_address2': billing_address_2, 52 | 'billing_city': billing_city, 53 | 'billing_country': billing_country, 54 | 'billing_email': email, 55 | 'billing_email_confirm': email, 56 | 'billing_first_name': first_name, 57 | 'billing_last_name': last_name, 58 | 'billing_phone': phone_number, 59 | 'billing_state': billing_state_abbrv, 60 | 'billing_zip': billing_zip, 61 | 'cc_cvv': card_cvv, 62 | 'cc_exp_month': card_exp_month, 63 | 'cc_exp_year': card_exp_year, 64 | 'cc_number': card_number, 65 | 'cc_type': card_type, 66 | 'email_opt_in': '1', 67 | 'form_build_id': form_id, 68 | 'form_id': 'cart_checkout_form', 69 | 'gc_num': '', 70 | 'shipping_address1': shipping_address_1, 71 | 'shipping_address2': shipping_address_2, 72 | 'shipping_city': shipping_city, 73 | 'shipping_first_name': first_name, 74 | 'shipping_last_name': last_name, 75 | 'shipping_method': '0', 76 | 'shipping_state': shipping_state, 77 | 'shipping_zip': shipping_zip 78 | } 79 | 80 | response = session.post('https://www.jimmyjazz.com/cart/checkout', data=payload, headers=headers) 81 | 82 | response = session.get('https://www.jimmyjazz.com/cart/confirm') 83 | soup = bs(response.text, 'html.parser') 84 | form_id = soup.find('input', {'name': 'form_build_id'})['id'] 85 | 86 | payload = { 87 | 'form_build_id': form_id, 88 | 'form_id': 'cart_confirm_form' 89 | } 90 | response = session.post('https://www.jimmyjazz.com/cart/confirm', data=payload, headers=headers) 91 | try: 92 | soup = bs(response.text, 'html.parser') 93 | error = soup.find('div', {'class': 'messages error'}).text 94 | print(error) 95 | except: 96 | print('Checkout was successful!') 97 | 98 | 99 | # Main 100 | start = timeit.default_timer() 101 | session = requests.Session() 102 | headers = { 103 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'} 104 | 105 | if use_early_link: 106 | if add_to_cart(early_link, shoe_size): 107 | checkout() 108 | else: 109 | print('Size ' + shoe_size + ' not available') 110 | 111 | stop = timeit.default_timer() 112 | print(stop - start) 113 | -------------------------------------------------------------------------------- /Scripts/kithnyc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import requests 3 | import timeit 4 | from bs4 import BeautifulSoup as bs 5 | from getconf import * 6 | 7 | # TODO: keywords, paypal checkout method, login method 8 | 9 | """ 10 | Note: 11 | Shipping address and billing must be the same 12 | 13 | """ 14 | 15 | # User input 16 | use_early_link = True 17 | base_url = 'https://kithnyc.com' 18 | shop_url = 'https://shop.kithnyc.com' 19 | early_link = base_url + '/collections/footwear/products/asics-gel-lyte-iii-millionaires-row' 20 | use_keyword = False 21 | shoe_size = '4' 22 | 23 | 24 | # Functions 25 | def add_to_cart(early_link, shoe_size): 26 | response = session.get(early_link, headers=headers) 27 | soup = bs(response.text, 'html.parser') 28 | 29 | available_sizes = [] 30 | size_ids = [] 31 | size_box = soup.find('select', {'id': 'variant-listbox'}) 32 | 33 | for options in size_box.find_all('option'): 34 | available_sizes.append(options.text) 35 | size_ids.append(options['value']) 36 | 37 | if shoe_size in available_sizes: 38 | pos = available_sizes.index(shoe_size) 39 | id = size_ids[pos] 40 | payload = { 41 | 'id': id, 42 | 'quantity': '1' 43 | } 44 | session.post(base_url + '/cart/add.js', data=payload, headers=headers) 45 | return 1 46 | else: 47 | return 0 48 | 49 | 50 | def checkout(): 51 | response = session.get(base_url + '/cart', headers=headers) 52 | 53 | response = session.get(base_url + '/checkout', headers=headers) 54 | 55 | soup = bs(response.text, 'html.parser') 56 | form = soup.find('form', {'class': 'edit_checkout'}) 57 | 58 | payload = { 59 | '_method': 'patch', 60 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 61 | 'button': '', 62 | 'checkout[client_details][browser_height]': '728', 63 | 'checkout[client_details][browser_width]': '1280', 64 | 'checkout[client_details][javascript_enabled]': '0', 65 | 'checkout[email]': email, 66 | 'checkout[shipping_address][address1]': shipping_address_1, 67 | 'checkout[shipping_address][address2]': '', 68 | 'checkout[shipping_address][city]': shipping_city, 69 | 'checkout[shipping_address][country]': shipping_country, 70 | 'checkout[shipping_address][first_name]': first_name, 71 | 'checkout[shipping_address][last_name]': last_name, 72 | 'checkout[shipping_address][phone]': phone_number, 73 | 'checkout[shipping_address][province]': ',,' + shipping_state, 74 | 'checkout[shipping_address][zip]': shipping_zip, 75 | 'previous_step': 'contact_information', 76 | 'remember_me': 'false', 77 | 'step': 'shipping_method', 78 | 'utf8': '✓' 79 | } 80 | 81 | response = session.post(shop_url + form['action'], data=payload, headers=headers) # customer info 82 | 83 | soup = bs(response.text, 'html.parser') 84 | form = soup.find('form', {'class': 'edit_checkout'}) 85 | 86 | payload = { 87 | '_method': 'patch', 88 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 89 | 'button': '', 90 | 'checkout[client_details][browser_height]': '728', 91 | 'checkout[client_details][browser_width]': '1280', 92 | 'checkout[client_details][javascript_enabled]': '0', 93 | 'checkout[shipping_rate][id]': 'shopify-UPS%20GROUND%20(5-7%20business%20days)-10.00', 94 | 'previous_step': 'shipping_method', 95 | 'step': 'payment_method', 96 | 'utf8': '✓' 97 | } 98 | 99 | session.post(shop_url + form['action'], data=payload, headers=headers) # shipping 100 | 101 | response = session.get(shop_url + form['action'] + '?step=payment_method', headers=headers) # payment 102 | 103 | soup = bs(response.text, 'html.parser') 104 | form = soup.find_all('form', {'class': 'edit_checkout'})[-1] 105 | 106 | payload = { 107 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 108 | 'c': form.find('input', {'name': 'c'})['value'], 109 | 'd': form.find('input', {'name': 'd'})['value'], 110 | 'checkout[buyer_accepts_marketing]': '0', 111 | 'checkout[client_details][browser_height]': '728', 112 | 'checkout[client_details][browser_width]': '1280', 113 | 'checkout[client_details][javascript_enabled]': '1', 114 | 'checkout[credit_card][month]': card_exp_month, 115 | 'checkout[credit_card][name]': first_name + ' ' + last_name, 116 | 'checkout[credit_card][number]': card_exp_month.strip('0'), 117 | 'checkout[credit_card][verification_value]': card_cvv, 118 | 'checkout[credit_card][year]': card_exp_year, 119 | 'checkout[different_billing_address]': 'false', 120 | 'checkout[payment_gateway]': form.find('input', {'name': 'checkout[payment_gateway]'})['value'], 121 | 'complete': '1', 122 | 'expiry': card_exp_month + '/' + card_exp_year[-2:], 123 | 'previous_step': 'payment_method', 124 | 's':'', 125 | 'step':'', 126 | 'utf8': '✓' 127 | } 128 | 129 | response = session.post(form['action'], data=payload, headers=headers) # payment 130 | 131 | 132 | # Main 133 | start = timeit.default_timer() 134 | session = requests.Session() 135 | headers = { 136 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'} 137 | 138 | if use_early_link: 139 | if add_to_cart(early_link, shoe_size): 140 | checkout() 141 | else: 142 | print('Size ' + shoe_size + ' not available') 143 | 144 | stop = timeit.default_timer() 145 | print(stop - start) 146 | -------------------------------------------------------------------------------- /Scripts/makeinfo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import json 4 | 5 | """An interactive script for generating userinfo.json""" 6 | if sys.version_info[0] == 2: 7 | input = raw_input 8 | 9 | configuration = {} 10 | 11 | print("You may simply press without inputting anything to any of") 12 | print("these questions, but this may produce strange errors.") 13 | 14 | configuration["first_name"] = input("Please enter your first name: ") 15 | configuration["last_name"] = input("Please enter your last name: ") 16 | configuration["phone_number"] = input("Please enter your phone number: ") 17 | configuration["email"] = input("Please enter your email address: ") 18 | configuration["shipping_address_1"] = input("Please enter the first line of your shipping address: ") 19 | configuration["shipping_address_2"] = input( 20 | "Please enter the second line of your shipping address (hit if the second line is an apartment/suite number): ") 21 | configuration["shipping_apt_suite"] = input("Please enter your apartment/suite number, if applicable: ") 22 | configuration["shipping_city"] = input("Please enter your shipping city: ") 23 | configuration["shipping_state"] = input("Please enter your shipping state (not abbreviated): ") 24 | configuration["shipping_state_abbrv"] = input("Please enter your shipping state (abbreviated): ") 25 | configuration["shipping_country"] = input("Please enter your shipping country (not abbreviated): ") 26 | configuration["shipping_country_abbrv"] = input("Please enter your shipping country (abbreviated): ") 27 | configuration["shipping_zip"] = input("Please enter your shipping zip/post code: ") 28 | 29 | billing = input("Is your billing address different than the shipping address? [Y/N]: ").title() 30 | if billing in ["Y", "Yes"]: 31 | configuration["billing_address_1"] = input("Please enter the first line of your billing address: ") 32 | configuration["billing_address_2"] = input( 33 | "Please enter the second line of your billing address (hit if the second line is an apartment/suite number): ") 34 | configuration["billing_apt_suite"] = input("Please enter your apartment/suite number, if applicable: ") 35 | configuration["billing_city"] = input("Please enter your billing city: ") 36 | configuration["billing_state"] = input("Please enter your billing state (not abbreviated): ") 37 | configuration["billing_state_abbrv"] = input("Please enter your billing state (abbreviated): ") 38 | configuration["billing_country"] = input("Please enter your billing country: ") 39 | configuration["billing_zip"] = input("Please enter your billing zip/post code: ") 40 | else: 41 | configuration["billing_address_1"] = configuration["shipping_address_1"] 42 | configuration["billing_address_2"] = configuration["shipping_address_2"] 43 | configuration["billing_apt_suite"] = configuration["shipping_apt_suite"] 44 | configuration["billing_city"] = configuration["shipping_city"] 45 | configuration["billing_state"] = configuration["shipping_state"] 46 | configuration["billing_state_abbrv"] = configuration["shipping_state_abbrv"] 47 | configuration["billing_country"] = configuration["shipping_country"] 48 | configuration["billing_country_abbrv"] = configuration["shipping_country_abbrv"] 49 | configuration["billing_zip"] = configuration["shipping_zip"] 50 | 51 | configuration["card_type"] = input("Please enter your credit card type (Visa, MasterCard, Amex...)? ") 52 | print("") 53 | print( 54 | "It is recommended that, if you are testing, you input a real card number but a fake CVV. This way, checkout will proceed as normal so you can see what will occur, but nothing will be charged to your account.") 55 | print("") 56 | configuration["card_number"] = input("Please enter your credit card number: ") 57 | configuration["card_cvv"] = input("Please enter the CVV for that credit card: ") 58 | configuration["card_exp_year"] = input("Please enter your card expiration year: ") 59 | configuration["card_exp_month"] = input("Please enter your card expiration month: ") 60 | configuration["name_on_card"] = input("Please enter your name as it appears on this card: ") 61 | print("Thank you! All done.") 62 | 63 | with open("userinfo.json", "w") as conffile: 64 | json.dump(configuration, conffile, sort_keys=True, indent=4) 65 | -------------------------------------------------------------------------------- /Scripts/nakedcph.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This is the checkout process on NakedCPH for an HSBC card with Verified by Visa 3 | # Unfortunately, this is will likely need to be done on a case by case basis for 4 | # different cart types. 5 | 6 | import requests 7 | import re 8 | import time 9 | import timeit 10 | from bs4 import BeautifulSoup as bs 11 | from getconf import * 12 | 13 | def checkout(first, last): 14 | i = first 15 | while first <= last: 16 | print ('Trying: ' + str(first)) 17 | password = '' # Your Verified by Visa password 18 | soup = None 19 | while soup is None: 20 | try: 21 | print ('Adding to cart') 22 | payload = { 23 | 'action' : 'add', 24 | 'item_pid' : first, 25 | 'ajax' : '1' 26 | } 27 | response = session.post('http://www.nakedcph.com/cart', data=payload) 28 | soup = bs(response.text, 'html.parser') 29 | except Exception: 30 | pass 31 | print (soup) 32 | if soup.find('a').getText() != 'Cart (0)': 33 | none = None 34 | while none is None: 35 | try: 36 | payload = { 37 | 'formid' : 'details.anonymous', 38 | 'email' : email, 39 | 'email_repeat' : email, 40 | 'first_name' : first_name, 41 | 'surname' : last_name, 42 | 'address' : shipping_address_1, 43 | 'address2' : shipping_apt_suite, 44 | 'zip' : shipping_zip, 45 | 'city' : shipping_city, 46 | 'state' : shipping_state, 47 | 'country' : shipping_country, 48 | 'phone' : phone_number 49 | } 50 | response = session.post('http://www.nakedcph.com/checkout/details', data=payload) 51 | none = 1 52 | except Exception: 53 | pass 54 | 55 | none = None 56 | while none is None: 57 | try: 58 | payoad = { 59 | 'mode' : 'user', 60 | 'shipping' : '6', # Need to figure out which countries these correspond to 61 | 'payment' : 'quickpay10secure' 62 | } 63 | response = session.post('http://www.nakedcph.com/checkout/handling', data=payload) 64 | none = 1 65 | except Exception: 66 | pass 67 | 68 | none = None 69 | while none is None: 70 | try: 71 | payload = { 72 | 'confirmed' : 'on' 73 | } 74 | response = session.post('http://www.nakedcph.com/checkout/confirm', data=payload) 75 | soup = bs(response.text, 'html.parser') 76 | none = 1 77 | except Exception: 78 | pass 79 | 80 | payload = { 81 | 'agreement_id' : soup.find('input', {'name' : 'agreement_id'})['value'], 82 | 'amount' : soup.find('input', {'name' : 'amount'})['value'], 83 | 'autocapture' : soup.find('input', {'name' : 'autocapture'})['value'], 84 | 'callbackurl' : soup.find('input', {'name' : 'callbackurl'})['value'], 85 | 'cancelurl' : soup.find('input', {'name' : 'cancelurl'})['value'], 86 | 'continueurl' : soup.find('input', {'name' : 'continueurl'})['value'], 87 | 'currency' : soup.find('input', {'name' : 'currency'})['value'], 88 | 'language' : soup.find('input', {'name' : 'language'})['value'], 89 | 'merchant_id' : soup.find('input', {'name' : 'merchant_id'})['value'], 90 | 'order_id' : soup.find('input', {'name' : 'order_id'})['value'], 91 | 'payment_methods' : soup.find('input', {'name' : 'payment_methods'})['value'], 92 | 'version' : soup.find('input', {'name' : 'version'})['value'], 93 | 'checksum' : soup.find('input', {'name' : 'checksum'})['value'] 94 | } 95 | response = session.post('https://payment.quickpay.net/', data=payload) 96 | soup = bs(response.text, 'html.parser') 97 | 98 | payload = { 99 | 'card_number' : card_number, 100 | 'month' : card_exp_month, 101 | 'year' : card_exp_year, 102 | 'cvd' : card_cvv, 103 | 'session_id' : soup.find('input', {'name' : 'session_id'})['value'] 104 | } 105 | 106 | # The 3d secure process should always be relatively similar for every card 107 | response = session.post('https://payment.quickpay.net/prepare_3d_secure', data=payload) 108 | soup = bs(response.text, 'html.parser') 109 | 110 | MD = soup.find('input', {'name' : 'MD'})['value'] 111 | PaReq = soup.find('input', {'name' : 'PaReq'})['value'] 112 | TermUrl = soup.find('input', {'name' : 'TermUrl'})['value'] 113 | 114 | payload = { 115 | 'MD' : MD, 116 | 'PaReq' : PaReq, 117 | 'TermUrl' : TermUrl 118 | } 119 | secure5link = soup.find('form', {'id' : 'secure_3d_form'})['action'] 120 | response = session.post(secure5link, data=payload) 121 | soup = bs(response.text, 'html.parser') 122 | 123 | payload = { 124 | 'executionTime' : '0', 125 | 'PaReq' : PaReq, 126 | 'MD' : MD, 127 | 'TermUrl' : TermUrl, 128 | 'deviceSignature' : '', 129 | 'DeviceID' : '', 130 | 'CallerID' : '', 131 | 'IpAddress' : '', 132 | 'cancelHit' : '', 133 | 'CookieType' : '2', 134 | 'AcsCookie' : '!@#Dummy#@!', 135 | 'dnaError' : '', 136 | 'mesc' : '', 137 | 'mescIterationCount' : '0', 138 | 'desc' : '', 139 | 'isDNADone' : 'false', 140 | 'ABSlog' : 'DSP;FlashLoadTime:639;DEVICEID;' 141 | } 142 | response = session.post(secure5link, data=payload) 143 | soup = bs(response.text, 'html.parser') 144 | pattern = re.compile('getPartialSlotDefinition\("(.*?)","(.*?)","(.*?)"\)') 145 | matches = pattern.findall(response.text) 146 | slotData = [] 147 | if len(matches) > 0: 148 | for match in matches: 149 | if len(match) > 0: 150 | slotData = match 151 | 152 | if not slotData == []: 153 | payload = { 154 | 'slotpin1' : password[int(slotData[0])-1], 155 | 'slotpin2' : password[int(slotData[1])-1], 156 | 'slotpin3' : password[int(slotData[2])-1], 157 | 'pin' : '0', 158 | 'submitted' : '1', 159 | 'authType' : 'Visa Password', 160 | 'cancelHit' : '0', 161 | 'forgotPassword' : '0', 162 | 'cardHolder' : name_on_card, 163 | 'authDefaultSelect' : 'Visa Password', 164 | 'AuthFallBack' : '', 165 | 'Phase' : 'passwd', 166 | 'pan' : 'XXXX XXXX XXXX ' + card_number[-4:], 167 | 'tryIndex' : '1', 168 | 'PaReq' : PaReq, 169 | 'TermUrl' : TermUrl, 170 | 'MD' : MD, 171 | 'PTerms' : '', 172 | 'PDescription' : '', 173 | 'PConditions' : '', 174 | 'ARCOTC' : '', 175 | 'ARCOTR' : '', 176 | 'Locale' : 'en_GB_hsbcvisadebit/', 177 | 'VSDCInput' : soup.find('input', {'name' : 'VSDCInput'})['value'], 178 | 'VSDCData' : '', 179 | 'ChipPluginName' : '', 180 | 'ChipPluginVersion' : '', # You need to check these values for your own card 181 | 'ChipPluginPresent' : 'TRUE', # Do you have a chip card? 182 | 'eAccessPresent' : 'FALSE', 183 | 'eAccessRequired' : 'FALSE', 184 | 'ChipSecret' : '', 185 | 'AcsCookie' : soup.find('input', {'name' : 'AcsCookie'})['value'], 186 | 'AcsCondData' : '1301', 187 | 'ABSlog' : 'GPP;INIT', 188 | 'DeviceID' : soup.find('input', {'name' : 'DeviceID'})['value'], 189 | 'CookieType' : '2' 190 | } 191 | TermUrl = soup.find('input', {'name' : 'TermUrl'})['value'] 192 | response = session.post('https://secure5.arcot.com/acspage/cap.cgi', data=payload) 193 | soup = bs(response.text, 'html.parser') 194 | 195 | payload = { 196 | 'PaRes' : soup.find('input', {'name' : 'PaRes'})['value'], 197 | 'MD' : MD, 198 | 'PaReq' : PaReq 199 | } 200 | response = session.post(TermUrl, data=payload) 201 | soup = bs(response.text, 'html.parser') 202 | 203 | response = session.get('https://payment.quickpay.net' + soup.find('a')['href']) 204 | soup = bs(response.text, 'html.parser') 205 | p = soup.find('p') 206 | while not p is None and p.getText() == 'Please wait while we process your payment...': 207 | response = session.get('https://payment.quickpay.net' + soup.find('a')['href']) 208 | soup = bs(response.text, 'html.parser') 209 | return 210 | 211 | print ('ORDER PLACED') 212 | else: 213 | print ('Verification was not needed') 214 | 215 | first = first + 1 216 | if first == last: 217 | first = i 218 | 219 | session = requests.session() 220 | first1 = 12345 221 | last1 = 67890 222 | checkout(first1, last1) # Only if you want a range of product IDS 223 | -------------------------------------------------------------------------------- /Scripts/overkill.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import re 3 | import json 4 | from bs4 import BeautifulSoup as bs 5 | from getconf import * 6 | def getIds(): 7 | global product_id 8 | global size_id 9 | for script in scripts: 10 | if 'spConfig =' in script.getText(): 11 | regex = re.compile(r'var spConfig = new Product.Config\((.*?)\);') 12 | match = regex.search(script.getText()) 13 | spConfig = json.loads(match.groups()[0]) 14 | for key in spConfig['attributes']: # Should only call once 15 | for product in spConfig['attributes'][key]['options']: 16 | if product['label_uk'] == uk_size: 17 | size_id = product['id'] 18 | product_id = spConfig['attributes'][key]['id'] 19 | 20 | def checkout(): 21 | print ('placeholder') 22 | 23 | 24 | uk_size = '8.5' 25 | early_link = 'https://www.overkillshop.com/en/nike-roshe-tiempo-vi-qs-853535-001.html' 26 | session = requests.session() 27 | response = session.get(early_link) 28 | soup = bs(response.text, 'html.parser') 29 | form = soup.find('form', {'id' : 'product_addtocart_form'}) 30 | scripts = soup.findAll('script') 31 | product_id = '' 32 | size_id = '' 33 | getIds() 34 | 35 | payload = { 36 | 'product' : form.find('input', {'name' : 'product'})['value'], 37 | 'related_product' : form.find('input', {'name' : 'related_product'})['value'], 38 | 'super_attribute[' + product_id + ']' : size_id, 39 | 'qty' : '1', 40 | 'gpc_add' : '1' 41 | } 42 | 43 | response = session.post(form['action'], data=payload) 44 | regex = re.compile(r'\\"(\d+)' + re.escape(r'\":{\"code\":\"' + shipping_state_abbrv + r'\"')) 45 | match = regex.search(response.text) 46 | region_id = match.groups()[0] 47 | response = session.get('https://www.overkillshop.com/en/checkout/onepage/') 48 | soup = bs(response.text, 'html.parser') 49 | form_key = soup.find('input', {'name' : 'form_key'})['value'] 50 | 51 | payload = { 52 | 'method' : 'guest' 53 | } 54 | 55 | response = session.post('https://www.overkillshop.com/en/checkout/onepage/saveMethod/', data=payload) 56 | 57 | payload = { 58 | 'billing[address_id]' : '', 59 | 'billing[firstname]' : first_name, 60 | 'billing[lastname]' : last_name, 61 | 'billing[company]' : '', 62 | 'billing[street][]' : shipping_address_1 + ', ' + shipping_apt_suite, 63 | 'billing[postcode]' : shipping_zip, 64 | 'billing[region_id]' : region_id, 65 | 'billing[region]' : '', 66 | 'billing[city]' : shipping_city, 67 | 'billing[country_id]' : 'US', 68 | 'billing[email]' : email, 69 | 'billing[telephone]' : phone_number, 70 | 'billing[fax]' : phone_number, 71 | 'billing[customer_password]' : '', 72 | 'billing[confirm_password]' : '', 73 | 'billing[save_in_address_book]' : '1', 74 | 'billing[use_for_shipping]' : '1' 75 | } 76 | 77 | response = session.post('https://www.overkillshop.com/en/checkout/onepage/saveBilling/', data=payload) 78 | 79 | payload = { 80 | 'shipping_method' : 'owebiashipping1_international' 81 | } 82 | 83 | response = session.post('https://www.overkillshop.com/en/checkout/onepage/saveShippingMethod/', data=payload) 84 | 85 | 86 | payload = { 87 | 'payment[method]' : 'paypal_standard', 88 | 'agreement[1]' : '1', 89 | 'agreement[2]' : '1' 90 | } 91 | 92 | response = session.post('https://www.overkillshop.com/en/checkout/onepage/saveOrder/form_key/' + form_key + '/', data=payload) 93 | 94 | response = session.get('https://www.overkillshop.com/en/paypal/standard/redirect/') 95 | 96 | # Paypal checkout (should we standardize this?) 97 | soup = bs(response.text, 'html.parser') 98 | form = soup.find('form') 99 | inputs = form.findAll('input') 100 | payload = {} 101 | for input_tag in inputs: 102 | if not 'Click here if you are not' in input_tag['value']: 103 | payload[input_tag['name']] = input_tag['value'] 104 | 105 | response = session.post('https://www.paypal.com/cgi-bin/webscr', data=payload) 106 | print (response.text) 107 | -------------------------------------------------------------------------------- /Scripts/palaceskateboards.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import requests 3 | import re 4 | import timeit 5 | from multiprocessing.dummy import Pool as ThreadPool 6 | from bs4 import BeautifulSoup as bs 7 | from getconf import * 8 | 9 | #User input 10 | size = 'Medium' 11 | use_early_link = True 12 | early_link = 'http://shop-usa.palaceskateboards.com/products/reversible-thinsulate-green-gables-puritan-grey' 13 | use_keyword = False 14 | #TODO: Make the logic for keyword checkout 15 | 16 | #Functions 17 | def checkout(): 18 | response = session.get('http://shop-usa.palaceskateboards.com/cart') 19 | soup = bs(response.text, 'html.parser') 20 | 21 | form = soup.find('form', {'action' : '/cart'}) 22 | 23 | payload = { 24 | form.find('input', {'name' : re.compile('(?<=updates\[)(.*)(?=])')})['name'] : form.find('input', {'name' : re.compile('(?<=updates\[)(.*)(?=])')})['value'], 25 | 'checkout' : 'Checkout', 26 | 'note' : form.find('input', {'name' : 'note'})['value'] 27 | } 28 | 29 | response = session.post('http://shop-usa.palaceskateboards.com/cart', data=payload) 30 | soup = bs(response.text, 'html.parser') 31 | 32 | form = soup.find('form', {'action' : re.compile('(?<=shop-usa.palaceskateboards.com)(.*)(?=/checkouts/)')}) 33 | checkout_url = form['action'] # For later 34 | 35 | payload = { 36 | 'utf8' : '✓', 37 | '_method' : 'patch', 38 | 'authenticity_token' : form.find('input', {'name' : 'authenticity_token'})['value'], 39 | 'previous_step' : 'contact_information', 40 | 'step' : 'shipping_method', 41 | 'checkout[email]' : email, 42 | 'checkout[shipping_address][first_name]' : first_name, 43 | 'checkout[shipping_address][last_name]' : last_name, 44 | 'checkout[shipping_address][address1]' : shipping_address_1, 45 | 'checkout[shipping_address][address2]' : shipping_apt_suite, 46 | 'checkout[shipping_address][city]' : shipping_city, 47 | 'checkout[shipping_address][country]' : 'United States', 48 | 'checkout[shipping_address][province]' : '', 49 | 'checkout[shipping_address][province]' : '', 50 | 'checkout[shipping_address][province]' : shipping_state, 51 | 'checkout[shipping_address][zip]' : shipping_zip, 52 | 'checkout[shipping_address][phone]' : phone_number, 53 | 'remember_me' : 'false', 54 | 'button' : '', 55 | 'checkout[client_details][browser_width]' : '123', 56 | 'checkout[client_details][browser_height]' : '456', 57 | 'checkout[client_details][javascript_enabled]' : '1' 58 | } 59 | 60 | response = session.post(form['action'], data=payload) 61 | soup = bs(response.text, 'html.parser') 62 | 63 | form = soup.find('form', {'action' : re.compile('(?<=shop-usa.palaceskateboards.com)(.*)(?=/checkouts/)')}) 64 | 65 | payload = { 66 | 'utf8' : '✓', 67 | '_method' : 'patch', 68 | 'authenticity_token' : form.find('input', {'name' : 'authenticity_token'})['value'], 69 | 'previous_step' : 'shipping_method', 70 | 'step' : 'payment_method', 71 | 'checkout[shipping_rate][id]' : form.find('input', {'name' : 'checkout[shipping_rate][id]'})['value'], 72 | 'button' : '', 73 | 'checkout[client_details][browser_width]' : '123', 74 | 'checkout[client_details][browser_height]' : '456', 75 | 'checkout[client_details][javascript_enabled]' : '1' 76 | } 77 | 78 | response = session.post(form['action'], data=payload) 79 | soup = bs(response.text, 'html.parser') 80 | 81 | form = soup.find('form', {'data-payment-form' : re.compile('(?<=shop-usa.palaceskateboards.com)(.*)(?=/checkouts/)')}) 82 | 83 | payload = { 84 | 'utf8' : '✓', 85 | 'authenticity_token' : form.find('input', {'name' : 'authenticity_token'})['value'], 86 | 'previous_step' : 'payment_method', 87 | 'step' : '', 88 | 's' : '', 89 | 'c' : form.find('input', {'name' : 'c'})['value'], 90 | 'd' : form.find('input', {'name' : 'd'})['value'], 91 | 'checkout[payment_gateway]' : form.find('input', {'name' : 'checkout[payment_gateway]'})['value'], 92 | 'checkout[credit_card][number]' : card_number, 93 | 'checkout[credit_card][name]' : first_name + ' ' + last_name, 94 | 'checkout[credit_card][month]' : card_exp_month.strip('0'), 95 | 'checkout[credit_card][year]' : card_exp_year, 96 | 'expiry' : card_exp_month + ' / ' + card_exp_year[-2:], 97 | 'checkout[credit_card][verification_value]' : card_cvv, 98 | 'checkout[different_billing_address]' : 'false', 99 | 'complete' : '1', 100 | 'checkout[client_details][browser_width]' : '123', 101 | 'checkout[client_details][browser_height]' : '456', 102 | 'checkout[client_details][javascript_enabled]' : '1' 103 | } 104 | 105 | response = session.post(form['action'], data=payload) 106 | 107 | response = session.get(checkout_url) 108 | soup = bs(response.text, 'html.parser') 109 | print (soup) # So I think this works... I would need to check if it actually checks out the next time I want to buy palace... 110 | 111 | #Main 112 | start = timeit.default_timer() 113 | 114 | session = requests.session() 115 | 116 | if use_early_link: 117 | response = session.get(early_link) 118 | soup = bs(response.text, 'html.parser') 119 | 120 | size_codes = soup.find_all('option') 121 | size_code = '' 122 | for code in size_codes: 123 | if code.getText() == size: 124 | size_code = code['value'] 125 | continue 126 | 127 | payload = { 128 | 'id' : size_code, 129 | 'button' : 'Add to Cart' 130 | } 131 | 132 | response = session.post('http://shop-usa.palaceskateboards.com/cart/add', data=payload) 133 | 134 | checkout() 135 | 136 | stop = timeit.default_timer() 137 | print(stop - start) # Get the runtime 138 | -------------------------------------------------------------------------------- /Scripts/shiekhshoes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import requests 3 | import re 4 | import timeit 5 | import json 6 | from multiprocessing.dummy import Pool as ThreadPool 7 | from bs4 import BeautifulSoup as bs 8 | from getconf import * 9 | 10 | # User input 11 | size = '' 12 | use_early_link = True 13 | early_link = '' 14 | use_keyword = False 15 | # TODO: Make the logic for keyword checkout 16 | 17 | 18 | # Functions 19 | def checkout(): # USA checkout 20 | # TODO: Get rid of this by making a list of state codes 21 | response = session.get('https://www.shiekhshoes.com/checkout.aspx?pType=cc') 22 | 23 | soup = bs(response.text, 'html.parser') 24 | 25 | state_ids = soup.find_all('option') 26 | state_id = '' 27 | for state in state_ids: 28 | if state.getText() == shipping_state: 29 | state_id = state['value'] 30 | continue 31 | 32 | payload = { 33 | 'Key': '1', 34 | 'Value': 'UPS ($0.00)' 35 | } 36 | 37 | response = session.post('https://www.shiekhshoes.com/api/ShoppingCart/UpdateShippingMethod', data=payload) 38 | 39 | payload = { 40 | '__VIEWSTATEGENERATOR': '277BF4AB', 41 | 'blackbox': '', 42 | 'ShippingCountryId': '222', # USA code 43 | 'ShippingFirstName': first_name, 44 | 'ShippingLastName': last_name, 45 | 'ShippingAddress1': shipping_address_1, 46 | 'ShippingAddress2': shipping_address_2, 47 | 'ShippingAptSuite': shipping_apt_suite, 48 | 'ShippingZip': shipping_zip, 49 | 'ShippingCity': shipping_city, 50 | 'ShippingStateId': state_id, 51 | 'ShippingMethodId': '1', 52 | 'BillingAddressSameAsSippingAddress': 'true', 53 | 'BillingFirstName': first_name, 54 | 'BillingLastName': last_name, 55 | 'BillingCardType': card_type, 56 | 'BillingCardNumber': card_number, 57 | 'BillingCardExpirationMonth': card_exp_month, 58 | 'BillingCardExpirationYear': card_exp_year, 59 | 'BillingCardSecurityCode': card_cvv, 60 | 'OrderNote': '', 61 | 'PhoneNumber': phone_number, 62 | 'GuestEmail': email, 63 | 'CacheStatus': 'cached', 64 | 'HasShippingAddress': 'false', 65 | 'PayWithPayPal': 'false', 66 | 'CustomerEmailAddress': '', 67 | 'CustomerFirstName': '', 68 | 'CustomerLastName': '' 69 | } 70 | 71 | response = session.post('https://www.shiekhshoes.com/api/ShoppingCart/ProcessCheckout', data=payload) 72 | print(response.text) 73 | 74 | # Main 75 | start = timeit.default_timer() 76 | 77 | session = requests.Session() 78 | 79 | if use_early_link: 80 | response = session.get(early_link) 81 | soup = bs(response.text, 'html.parser') 82 | 83 | size_codes = soup.find_all('a', {'class': 'selectSize'}) 84 | size_code = '' 85 | for code in size_codes: 86 | if code['data-size'] == size: 87 | size_code = code['data-stock'] 88 | continue 89 | 90 | payload = { 91 | '': size_code + ',0' 92 | } 93 | 94 | response = session.post('http://www.shiekhshoes.com/api/ShoppingCart/AddToCart', data=payload) 95 | checkout() 96 | 97 | stop = timeit.default_timer() 98 | print(stop - start) # Get the runtime 99 | -------------------------------------------------------------------------------- /Scripts/sneakersnstuff.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import requests 3 | import timeit 4 | from bs4 import BeautifulSoup as bs 5 | from getconf import * 6 | 7 | base_url = "http://www.sneakersnstuff.com/en/" 8 | 9 | #User Vars 10 | early_link = 'product/23807/new-balance-epic-tr-blueberry' 11 | shoe_size = '8' 12 | 13 | def checkout (): 14 | #TODO: SNS uses ayden for payment processing 15 | #Calls a URL that looks like so: 16 | ''' 17 | https://live.adyen.com/hpp/pay.shtml? 18 | paymentAmount=1800 19 | ¤cyCode=USD 20 | &skinCode=f4J2tsmj 21 | &merchantReference=3076306 22 | &shopperReference=2213612 23 | &shopperEmail= 24 | &merchantAccount=SneakersnstuffCOM 25 | &sessionValidity=2016-06-18T17%3a09%3a12Z 26 | &shipBeforeDate=2016-06-25T16%3a59%3a12Z 27 | &allowedMethods=card 28 | &resURL=http%3a%2f%2fwww.sneakersnstuff.com%2fadyen%2freturn 29 | &countryCode=US 30 | &merchantSig=Bk2R0n7GdFH9t911QknLhsO%2b53Y%3d 31 | &shopperLocale=en 32 | &orderData=H4sIAAAAAAAEAK2QsQrCMBCGd8F3CMFVtJtDzVAXF6c8wTUX9DBNzuQ69O1tpYJDHQS374f%2fjo%2b%2fFmiDVy5AKUedMvq8JfFd0Wa9UqqWNuHwwinkmSbG9xH64jKxUIranIF5UDa5e1FNc1KWwfk52w5C2F08Ut%2fVO8GlZ48eopAM2lTfKpzJeW02h4%2fCiPkHSysQETIqeyNmitc%2f6FT7JZ8R5gVHmqY2T53OD0dyAQAA 33 | &billingAddress.street= Line 1 and 2 34 | &billingAddress.city= 35 | &billingAddress.postalCode= 36 | &billingAddress.stateOrProvince= 37 | &billingAddress.country=US 38 | :return: 39 | ''' 40 | return 41 | 42 | def add_to_cart(url, size): 43 | size_code = '' 44 | session = requests.Session() 45 | response = session.get(base_url + url) 46 | 47 | soup = bs(response.text, 'html.parser') 48 | form = soup.find('form', { 'id': 'add-to-cart-form'}) 49 | size_divs = form.find_all('div', { 'class': 'size-button property available'}) 50 | print ('Sizes available: {}'.format(len(size_divs))) 51 | anti_token = form.find('input', {'name': '_AntiCsrfToken'})['value'] 52 | 53 | for div in size_divs: 54 | #TODO: Perhaps there is a better way for size systems? 55 | if (div.text.strip().replace('US ', '') == size): 56 | print ('Found') 57 | size_code = div['data-productid'] 58 | break 59 | if not size_code: 60 | print('Could not find size!') 61 | return 62 | 63 | payload = { 64 | '_AntiCsrfToken': anti_token, 65 | 'partial': 'cart-summary', 66 | 'id': size_code 67 | } 68 | 69 | response = session.post(base_url + "cart/add", data=payload) 70 | print (response) 71 | # checkout() 72 | 73 | 74 | # Main 75 | start = timeit.default_timer() 76 | if early_link: 77 | add_to_cart(early_link, shoe_size) 78 | # else 79 | #TODO: keyword logic 80 | 81 | stop = timeit.default_timer() 82 | print ("Runtime: {}".format(stop - start)) 83 | -------------------------------------------------------------------------------- /Scripts/supremenewyork.py: -------------------------------------------------------------------------------- 1 | from multiprocessing.dummy import Pool as ThreadPool 2 | from bs4 import BeautifulSoup as bs 3 | import requests 4 | import sys 5 | import re 6 | from getconf import * 7 | from atclibs import * 8 | 9 | # TO DO: scrape for early links 10 | 11 | # Constants 12 | base_url = 'http://www.supremenewyork.com' 13 | 14 | # Inputs 15 | keywords_category = ['accessories'] # Demo stuff, feel free to change 16 | keywords_model = ['crew', 'socks'] 17 | keywords_style = ['white'] 18 | 19 | # if there is no size, such as for socks, the size is OS 20 | size = 'OS' 21 | 22 | use_early_link = False 23 | 24 | early_link = '' 25 | 26 | 27 | # early_link = 'http://www.supremenewyork.com/shop/jackets/nzpacvjtk' #sold out 28 | # early_link = 'http://www.supremenewyork.com/shop/shirts/r1k32vjf4/sblz8csj2' # mult sizes 29 | # early_link = 'http://www.supremenewyork.com/shop/accessories/kcgevis8r/xiot9byq4' #one size 30 | 31 | 32 | # Functions 33 | def product_page(url): 34 | print('Finding matching products...', end='') 35 | session = requests.Session() 36 | session.headers.update({ 37 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) ' 38 | 'Chrome/52.0.2743.116 Safari/537.36', 39 | 'X-XHR-Referer': 'http://www.supremenewyork.com/shop/all', 40 | 'Referer': 'http://www.supremenewyork.com/shop/all/bags', 41 | 'Accept': 'text/html, application/xhtml+xml, application/xml', 42 | 'Accept-Encoding': 'gzip, deflate, sdch', 43 | 'Accept-Language': 'en-US,en;q=0.8,da;q=0.6', 44 | 'DNT': '1' 45 | }) 46 | 47 | response = session.get(base_url + url) 48 | soup = bs(response.text, 'html.parser') 49 | 50 | h1 = soup.find('h1', {'itemprop': 'name'}) 51 | 52 | p = soup.find('p', {'itemprop': 'model'}) 53 | 54 | match = [] 55 | 56 | if h1 is not None and p is not None: 57 | model = h1.string 58 | style = p.string 59 | 60 | for keyword in keywords_model: 61 | if keyword.title() in model: 62 | match.append(1) 63 | else: 64 | match.append(0) 65 | 66 | # add to cart 67 | if 0 not in match: 68 | match = [] 69 | for keyword in keywords_style: 70 | if keyword.title() in style: 71 | match.append(1) 72 | else: 73 | match.append(0) 74 | if 0 not in match: 75 | print('FOUND: ' + model + ' at ' + base_url + url) 76 | add_to_cart(soup, base_url + url) 77 | else: 78 | print('Sorry, couldnt find {} in {}'.format(model, style)) 79 | else: 80 | print('Sorry couldnt find what you are looking for') 81 | 82 | 83 | def add_to_cart(soup, url): 84 | product_name = soup.find('h1', {'itemprop': 'name'}).string 85 | print('Adding {} to cart...'.format(product_name)) 86 | session = requests.Session() 87 | session.headers.update({ 88 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) ' 89 | 'Chrome/52.0.2743.116 Safari/537.36', 90 | 'X-XHR-Referer': 'http://www.supremenewyork.com/shop/all', 91 | 'Referer': 'http://www.supremenewyork.com/shop/all/', 92 | 'Accept': 'text/html, application/xhtml+xml, application/xml', 93 | 'Accept-Encoding': 'gzip, deflate, sdch', 94 | 'Accept-Language': 'en-US,en;q=0.8,da;q=0.6', 95 | 'DNT': '1' 96 | }) 97 | form = soup.find('form', {'action': re.compile('(?<=/shop/)(.*)(?=/add)')}) 98 | csrf_token = soup.find('meta', {'name': 'csrf-token'})['content'] 99 | 100 | # find size 101 | sold_out = soup.find('fieldset', {'id': 'add-remove-buttons'}).find('b') 102 | if sold_out is not None: 103 | sys.exit('Sorry, product is sold out!') 104 | else: 105 | if size.upper() == 'OS': 106 | size_value = form.find('input', {'name': 'size'})['value'] 107 | else: 108 | try: 109 | size_value = soup.find('option', string=size.title())['value'] 110 | except: 111 | sys.exit('Sorry, {} is sold out!'.format(size)) 112 | 113 | if form is not None: 114 | payload = { 115 | 'utf8': '✓', 116 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 117 | 'size': size_value, 118 | 'commit': 'add to cart' 119 | } 120 | headers = { 121 | 'Accept': '*/*;q=0.5, text/javascript, application/javascript, application/ecmascript, application/x-ecmascript', 122 | 'Origin': 'http://www.supremenewyork.com', 123 | 'X-Requested-With': 'XMLHttpRequest', 124 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 125 | 'Referer': url, 126 | 'X-XHR-Referer': None, 127 | 'X-CSRF-Token': csrf_token, 128 | 'Accept-Encoding': 'gzip, deflate' 129 | } 130 | 131 | session.post(base_url + form['action'], data=payload, headers=headers) 132 | checkout(session) 133 | else: 134 | sys.exit('Sorry, product is sold out!') 135 | 136 | 137 | def checkout(session): 138 | print('Filling out checkout info...') 139 | response = session.get('https://www.supremenewyork.com/checkout') 140 | soup = bs(response.text, 'html.parser') 141 | form = soup.find('form', {'action': '/checkout'}) 142 | 143 | csrf_token = soup.find('meta', {'name': 'csrf-token'})['content'] 144 | headers = { 145 | 'Accept': 'text/html, */*; q=0.01', 146 | 'X-CSRF-Token': csrf_token, 147 | 'X-Requested-With': 'XMLHttpRequest', 148 | 'Referer': 'https://www.supremenewyork.com/checkout', 149 | 'Accept-Encoding': 'gzip, deflate, sdch, br' 150 | } 151 | 152 | country_abbrv = shipping_country_abbrv 153 | if country_abbrv == 'US': 154 | country_abbrv = 'USA' 155 | 156 | if card_type.lower() in ['mastercard', 'master card', 'master']: 157 | card_ = 'master' 158 | elif card_type.lower() == 'visa': 159 | card_ = 'visa' 160 | elif card_type.lower() == 'american express': 161 | card_ = 'american_express' 162 | else: 163 | sys.exit('You must be using a master, visa, or american express card') 164 | 165 | payload = { 166 | 'utf8': '✓', 167 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 168 | 'order[billing_name]': first_name + ' ' + last_name, 169 | 'order[email]': email, 170 | 'order[tel]': format_phone(phone_number), 171 | 'order[billing_address]': shipping_address_1, 172 | 'order[billing_address_2]': shipping_apt_suite, 173 | 'order[billing_zip]': shipping_zip, 174 | 'order[billing_city]': shipping_city, 175 | 'order[billing_state]': shipping_state, 176 | 'order[billing_country]': country_abbrv, 177 | 'same_as_billing_address': '1', 178 | # 'store_address': '0', 179 | 'store_credit_id': '', 180 | 'credit_card[type]': card_, 181 | 'credit_card[cnb]': format_card(card_number), 182 | 'credit_card[month]': card_exp_month, 183 | 'credit_card[year]': card_exp_year, 184 | 'credit_card[vval]': card_cvv, 185 | 'order[terms]': '1', 186 | 'hpcvv': '', 187 | 'cnt': '2' 188 | } 189 | 190 | response = session.get('https://www.supremenewyork.com/checkout.js', data=payload, headers=headers) 191 | 192 | payload = { 193 | 'utf8': '✓', 194 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 195 | 'order[billing_name]': first_name + ' ' + last_name, 196 | 'order[email]': email, 197 | 'order[tel]': format_phone(phone_number), 198 | 'order[billing_address]': shipping_address_1, 199 | 'order[billing_address_2]': shipping_apt_suite, 200 | 'order[billing_zip]': shipping_zip, 201 | 'order[billing_city]': shipping_city, 202 | 'order[billing_state]': shipping_state_abbrv, 203 | 'order[billing_country]': country_abbrv, 204 | 'same_as_billing_address': '1', 205 | 'store_credit_id': '', 206 | 'store_address': '1', 207 | 'credit_card[type]': card_type, 208 | 'credit_card[cnb]': format_card(card_number), 209 | 'credit_card[month]': card_exp_month, 210 | 'credit_card[year]': card_exp_year, 211 | 'credit_card[vval]': card_cvv, 212 | 'order[terms]': '1', 213 | 'hpcvv': '' 214 | } 215 | 216 | headers = { 217 | 'Origin': 'https://www.supremenewyork.com', 218 | 'Content-Type': 'application/x-www-form-urlencoded', 219 | 'Referer': 'https://www.supremenewyork.com/checkout', 220 | 'Accept-Encoding': 'gzip, deflate, br' 221 | } 222 | 223 | response = session.post('https://www.supremenewyork.com/checkout', data=payload, headers=headers) 224 | if 'Your order has been submitted' in response.text: 225 | print('Checkout was successful, check for a confirmation email!') 226 | else: 227 | try: 228 | soup = bs(response.text, 'html.parser') 229 | error_msg = soup.find('div', {'class': 'errors'}) 230 | if error_msg is None: 231 | print(soup.find('p').text) 232 | else: 233 | print('\n' + 'ERROR: ' + error_msg) 234 | except: 235 | print('Checkout failed') 236 | 237 | # Main 238 | tick() 239 | 240 | session1 = requests.Session() 241 | session1.headers.update({ 242 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) ' 243 | 'Chrome/52.0.2743.116 Safari/537.36', 244 | 'Upgrade-Insecure-Requests': '1', 245 | 'DNT': '1', 246 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 247 | 'Accept-Encoding': 'gzip, deflate, sdch', 248 | 'Accept-Language': 'en-US,en;q=0.8,da;q=0.6' 249 | }) 250 | 251 | if use_early_link: 252 | try: 253 | response1 = session1.get(early_link) 254 | soup = bs(response1.text, 'html.parser') 255 | except: 256 | sys.exit('Unable to connect to site...') 257 | add_to_cart(soup, early_link) 258 | else: 259 | try: 260 | url = base_url + '/shop/all/' + keywords_category[0] + '/' 261 | response1 = session1.get(url) 262 | except: 263 | sys.exit('Unable to connect to site...') 264 | soup1 = bs(response1.text, 'html.parser') 265 | links1 = soup1.find_all('a', href=True) 266 | links_by_keyword1 = [] 267 | for link in links1: 268 | for keyword in keywords_category: 269 | product_link = link['href'] 270 | if keyword in product_link and 'all' not in product_link: 271 | if product_link not in links_by_keyword1: 272 | links_by_keyword1.append(link['href']) 273 | pool1 = ThreadPool(len(links_by_keyword1)) 274 | result1 = pool1.map(product_page, links_by_keyword1) 275 | 276 | tock() # runtime 277 | -------------------------------------------------------------------------------- /Scripts/supremenewyork_v3.py: -------------------------------------------------------------------------------- 1 | from apscheduler.schedulers.blocking import BlockingScheduler 2 | from multiprocessing.dummy import Pool as ThreadPool 3 | from bs4 import BeautifulSoup as bs 4 | import requests 5 | import timeit 6 | import datetime 7 | import time 8 | import sys 9 | import re 10 | from getconf import * 11 | 12 | # TO DO: scrape for early links 13 | 14 | # Constants 15 | base_url = 'http://www.supremenewyork.com' 16 | 17 | # Inputs 18 | keywords_category = ['shirts'] # Demo stuff, feel free to change 19 | keywords_model = ['mini', 'shadow', 'plaid', 'shirt'] 20 | keywords_style = ['blue'] 21 | 22 | size = 'medium' 23 | 24 | use_early_link = False 25 | 26 | early_link = '' 27 | # early_link = 'http://www.supremenewyork.com/shop/jackets/nzpacvjtk' #sold out 28 | # early_link = 'http://www.supremenewyork.com/shop/shirts/r1k32vjf4/sblz8csj2' # mult sizes 29 | # early_link = 'http://www.supremenewyork.com/shop/accessories/kcgevis8r/xiot9byq4' #one size 30 | 31 | 32 | # Functions 33 | def product_page(url): 34 | print('Finding matching products...') 35 | session = requests.Session() 36 | session.headers.update({ 37 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) ' 38 | 'Chrome/52.0.2743.116 Safari/537.36', 39 | 'X-XHR-Referer': 'http://www.supremenewyork.com/shop/all', 40 | 'Referer': 'http://www.supremenewyork.com/shop/all/bags', 41 | 'Accept': 'text/html, application/xhtml+xml, application/xml', 42 | 'Accept-Encoding': 'gzip, deflate, sdch', 43 | 'Accept-Language': 'en-US,en;q=0.8,da;q=0.6', 44 | 'DNT': '1' 45 | }) 46 | 47 | response = session.get(base_url + url) 48 | soup = bs(response.text, 'html.parser') 49 | 50 | h1 = soup.find('h1', {'itemprop': 'name'}) 51 | 52 | p = soup.find('p', {'itemprop': 'model'}) 53 | 54 | match = [] 55 | 56 | if h1 is not None and p is not None: 57 | model = h1.string 58 | style = p.string 59 | 60 | for keyword in keywords_model: 61 | if keyword.title() in model: 62 | match.append(1) 63 | else: 64 | match.append(0) 65 | 66 | # add to cart 67 | if 0 not in match: 68 | match = [] 69 | for keyword in keywords_style: 70 | if keyword.title() in style: 71 | match.append(1) 72 | else: 73 | match.append(0) 74 | if 0 not in match: 75 | print('FOUND: ' + model + ' at ' + base_url + url) 76 | add_to_cart(soup, base_url+url) 77 | else: 78 | sys.exit('Sorry, couldnt find {} in {}'.format(model, style)) 79 | 80 | 81 | def add_to_cart(soup, url): 82 | product_name = soup.find('h1',{'itemprop': 'name'}).string 83 | print('Adding {} to cart...'.format(product_name)) 84 | session = requests.Session() 85 | session.headers.update({ 86 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) ' 87 | 'Chrome/52.0.2743.116 Safari/537.36', 88 | 'X-XHR-Referer': 'http://www.supremenewyork.com/shop/all', 89 | 'Referer': 'http://www.supremenewyork.com/shop/all/', 90 | 'Accept': 'text/html, application/xhtml+xml, application/xml', 91 | 'Accept-Encoding': 'gzip, deflate, sdch', 92 | 'Accept-Language': 'en-US,en;q=0.8,da;q=0.6', 93 | 'DNT': '1' 94 | }) 95 | form = soup.find('form', {'action': re.compile('(?<=/shop/)(.*)(?=/add)')}) 96 | csrf_token = soup.find('meta', {'name': 'csrf-token'})['content'] 97 | 98 | # find size 99 | sold_out = soup.find('fieldset', {'id': 'add-remove-buttons'}).find('b') 100 | if sold_out is not None: 101 | sys.exit('Sorry, product is sold out!') 102 | else: 103 | if size.upper() == 'OS': 104 | size_value = form.find('input', {'name': 'size'})['value'] 105 | else: 106 | try: 107 | size_value = soup.find('option', string=size.title())['value'] 108 | except: 109 | sys.exit('Sorry, {} is sold out!'.format(size)) 110 | 111 | if form is not None: 112 | payload = { 113 | 'utf8': '✓', 114 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 115 | 'size': size_value, 116 | 'commit': 'add to cart' 117 | } 118 | headers = { 119 | 'Accept': '*/*;q=0.5, text/javascript, application/javascript, application/ecmascript, application/x-ecmascript', 120 | 'Origin': 'http://www.supremenewyork.com', 121 | 'X-Requested-With': 'XMLHttpRequest', 122 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 123 | 'Referer': url, 124 | 'X-XHR-Referer': None, 125 | 'X-CSRF-Token': csrf_token, 126 | 'Accept-Encoding': 'gzip, deflate' 127 | } 128 | 129 | session.post(base_url + form['action'], data=payload, headers=headers) 130 | print('Added to cart!') 131 | checkout(session) 132 | else: 133 | sys.exit('Sorry, product is sold out!') 134 | 135 | 136 | def format_phone(n): 137 | return '({}) {}-{}'.format(n[:3], n[3:6], n[6:]) 138 | 139 | 140 | def format_card(n): 141 | return '{} {} {} {}'.format(n[:4], n[4:8], n[8:12], n[12:]) 142 | 143 | 144 | def checkout(session): 145 | print('Filling out checkout info...') 146 | response = session.get('https://www.supremenewyork.com/checkout') 147 | soup = bs(response.text, 'html.parser') 148 | form = soup.find('form', {'action': '/checkout'}) 149 | 150 | csrf_token = soup.find('meta', {'name': 'csrf-token'})['content'] 151 | headers = { 152 | 'Accept': 'text/html, */*; q=0.01', 153 | 'X-CSRF-Token': csrf_token, 154 | 'X-Requested-With': 'XMLHttpRequest', 155 | 'Referer': 'https://www.supremenewyork.com/checkout', 156 | 'Accept-Encoding': 'gzip, deflate, sdch, br' 157 | } 158 | 159 | country_abbrv = shipping_country_abbrv 160 | if country_abbrv == 'US': 161 | country_abbrv = 'USA' 162 | 163 | payload = { 164 | 'utf8': '✓', 165 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 166 | 'order[billing_name]': first_name + ' ' + last_name, 167 | 'order[email]': email, 168 | 'order[tel]': format_phone(phone_number), 169 | 'order[billing_address]': shipping_address_1, 170 | 'order[billing_address_2]': shipping_apt_suite, 171 | 'order[billing_zip]': shipping_zip, 172 | 'order[billing_city]': shipping_city, 173 | 'order[billing_state]': shipping_state, 174 | 'order[billing_country]': country_abbrv, 175 | 'same_as_billing_address': '1', 176 | 'store_credit_id': '', 177 | 'credit_card[type]': card_type, 178 | 'credit_card[cnb]': format_card(card_number), 179 | 'credit_card[month]': card_exp_month, 180 | 'credit_card[year]': card_exp_year, 181 | 'credit_card[vval]': card_cvv, 182 | 'order[terms]': '1', 183 | 'hpcvv': '', 184 | 'cnt': '2' 185 | } 186 | response = session.get('https://www.supremenewyork.com/checkout.js', data=payload, headers=headers) 187 | payload = { 188 | 'utf8': '✓', 189 | 'authenticity_token': form.find('input', {'name': 'authenticity_token'})['value'], 190 | 'order[billing_name]': first_name + ' ' + last_name, 191 | 'order[email]': email, 192 | 'order[tel]': format_phone(phone_number), 193 | 'order[billing_address]': shipping_address_1, 194 | 'order[billing_address_2]': shipping_apt_suite, 195 | 'order[billing_zip]': shipping_zip, 196 | 'order[billing_city]': shipping_city, 197 | 'order[billing_state]': shipping_state_abbrv, 198 | 'order[billing_country]': country_abbrv, 199 | 'same_as_billing_address': '1', 200 | 'store_credit_id': '', 201 | 'credit_card[type]': card_type, 202 | 'credit_card[cnb]': format_card(card_number), 203 | 'credit_card[month]': card_exp_month, 204 | 'credit_card[year]': card_exp_year, 205 | 'credit_card[vval]': card_cvv, 206 | 'order[terms]': '1', 207 | 'hpcvv': '' 208 | } 209 | headers = { 210 | 'Origin': 'https://www.supremenewyork.com', 211 | 'Content-Type': 'application/x-www-form-urlencoded', 212 | 'Referer': 'https://www.supremenewyork.com/checkout', 213 | 'Accept-Encoding': 'gzip, deflate, br' 214 | } 215 | 216 | response = session.post('https://www.supremenewyork.com/checkout', data=payload, headers=headers) 217 | 218 | if 'Your order has been submitted' in response.text: 219 | print('Checkout was successful!') 220 | sys.exit(0) 221 | else: 222 | soup = bs(response.text, 'html.parser') 223 | print(soup.find('p').text) 224 | sys.exit(0) 225 | 226 | 227 | def on_time(): 228 | # Main 229 | print(datetime.datetime.now()) 230 | start = timeit.default_timer() 231 | 232 | session1 = requests.Session() 233 | session1.headers.update({ 234 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) ' 235 | 'Chrome/52.0.2743.116 Safari/537.36', 236 | 'Upgrade-Insecure-Requests': '1', 237 | 'DNT': '1', 238 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 239 | 'Accept-Encoding': 'gzip, deflate, sdch', 240 | 'Accept-Language': 'en-US,en;q=0.8,da;q=0.6' 241 | }) 242 | 243 | if use_early_link: 244 | try: 245 | response1 = session1.get(early_link) 246 | soup = bs(response1.text, 'html.parser') 247 | except: 248 | sys.exit('Unable to connect to site...') 249 | add_to_cart(soup, early_link) 250 | else: 251 | try: 252 | url = base_url + '/shop/all/' + keywords_category[0] + '/' 253 | response1 = session1.get(url) 254 | except: 255 | sys.exit('Unable to connect to site...') 256 | soup1 = bs(response1.text, 'html.parser') 257 | links1 = soup1.find_all('a', href=True) 258 | links_by_keyword1 = [] 259 | for link in links1: 260 | for keyword in keywords_category: 261 | product_link = link['href'] 262 | if keyword in product_link and 'all' not in product_link: 263 | if product_link not in links_by_keyword1: 264 | links_by_keyword1.append(link['href']) 265 | pool1 = ThreadPool(len(links_by_keyword1)) 266 | result1 = pool1.map(product_page, links_by_keyword1) # runtime 267 | 268 | sched = BlockingScheduler(timezone='America/New_York') 269 | sched.add_job(on_time, run_date='2016-09-01 10:59:59') 270 | sched.start() 271 | -------------------------------------------------------------------------------- /Scripts/test.py: -------------------------------------------------------------------------------- 1 | def flsize(size): 2 | size_ = size 3 | 4 | if size[-2:] != ".5": 5 | size_ = size + '.0' 6 | 7 | if float(size) < 10: 8 | size_ = '0' + size 9 | 10 | print(size_) 11 | 12 | flsize("5") 13 | flsize("5.5") 14 | flsize("9.5") 15 | flsize("10") 16 | flsize("10.5") 17 | flsize("15") 18 | flsize("15.5") -------------------------------------------------------------------------------- /Scripts/userinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "billing_address_1": "", 3 | "billing_address_2": "", 4 | "billing_apt_suite": "", 5 | "billing_city": "", 6 | "billing_country": "", 7 | "billing_country_abbrv": "", 8 | "billing_state": "", 9 | "billing_state_abbrv": "", 10 | "billing_zip": "", 11 | "card_cvv": "", 12 | "card_exp_month": "", 13 | "card_exp_year": "", 14 | "card_number": "", 15 | "card_type": "", 16 | "email": "", 17 | "first_name": "", 18 | "last_name": "", 19 | "name_on_card": "", 20 | "phone_number": "", 21 | "shipping_address_1": "", 22 | "shipping_address_2": "", 23 | "shipping_apt_suite": "", 24 | "shipping_city": "", 25 | "shipping_country": "", 26 | "shipping_country_abbrv": "", 27 | "shipping_state": "", 28 | "shipping_state_abbrv": "", 29 | "shipping_zip": "" 30 | } -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4==4.4.1 2 | bs4==0.0.1 3 | requests==2.10.0 4 | --------------------------------------------------------------------------------