Skip to content

Commit 1ec7f2a

Browse files
committed
Added files
1 parent e5c67f7 commit 1ec7f2a

7 files changed

+307
-0
lines changed

bot.py

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from selenium import webdriver
2+
from selenium.webdriver.support.ui import WebDriverWait
3+
from selenium.webdriver.common.by import By
4+
from selenium.webdriver.support import expected_conditions as EC
5+
from requests_html import HTMLSession
6+
from apscheduler.schedulers.background import BackgroundScheduler
7+
import time
8+
from time import gmtime, strftime
9+
import os, sys, winsound, random
10+
from src.mediaexpert import MediaExpert
11+
from src.settings import Settings
12+
13+
scheduler = BackgroundScheduler()
14+
15+
def is_available(settings):
16+
session = HTMLSession()
17+
product_link = settings.get_link()
18+
r = session.get(product_link)
19+
to_cart_button = r.html.find('div.c-offerBox_addToCart a', first=True)
20+
date = strftime("%Y-%m-%d %H:%M:%S", gmtime())
21+
if to_cart_button is not None and to_cart_button.text == 'Do koszyka':
22+
scheduler.remove_job('my_job_id')
23+
scheduler.shutdown(wait=False)
24+
ME = MediaExpert(settings)
25+
if ME.buy():
26+
winsound.PlaySound("SystemExit", winsound.SND_LOOP)
27+
return strftime("%Y-%m-%d %H:%M:%S", gmtime()) + ' ready to pay for item!'
28+
else:
29+
return 'some error occurred...'
30+
31+
return date + ' product unavailable.';
32+
33+
def start_scheduler(settings):
34+
sec = settings.get_interval()
35+
scheduler.add_job(lambda: print(is_available(settings)), 'interval', seconds=int(random.randint(sec-2, sec+3)), id='my_job_id')
36+
scheduler.start()
37+
38+
settings = Settings('./settings/settings.json')
39+
start_scheduler(settings)

requirements.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pip install selenium APScheduler requests-html
2+
3+
https://github.com/mozilla/geckodriver/releases

settings/__init__.py

Whitespace-only changes.

settings/settings.json

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"product_link": "https://www.mediaexpert.pl/gaming/playstation-5/konsole-ps5/konsola-sony-ps5",
3+
"is_company_purchase": false,
4+
"company_data": {
5+
"company_name": "",
6+
"nip": "",
7+
"mail": "",
8+
"street": "",
9+
"house_number": "",
10+
"apartment_number": "",
11+
"postcode": "",
12+
"city": "",
13+
"phone_number": ""
14+
},
15+
"personal_data": {
16+
"first_name": "",
17+
"last_name": "",
18+
"mail": "",
19+
"street": "",
20+
"house_number": "",
21+
"apartment_number": "",
22+
"postcode": "",
23+
"city": "",
24+
"phone_number": ""
25+
},
26+
"check_time_interval": 60,
27+
"wait_time": 600,
28+
"geckodriver_path": ""
29+
}

src/__init__.py

Whitespace-only changes.

src/mediaexpert.py

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
from selenium import webdriver
2+
from selenium.webdriver.support.ui import WebDriverWait
3+
from selenium.webdriver.common.by import By
4+
from selenium.webdriver.support import expected_conditions as EC
5+
import time
6+
import sys
7+
8+
class MediaExpert:
9+
def __init__(self, settings):
10+
if settings is not None:
11+
self.data = settings
12+
self.driver_path = settings.get_driver_path()
13+
self.product_link = settings.get_link()
14+
self.is_for_company = settings.is_for_company()
15+
self.wait_time = settings.get_wait_for_element()
16+
else:
17+
raise ValueError('there is no settings specified!')
18+
19+
def open_browser(self):
20+
try:
21+
print('opening browser...')
22+
self.driver = webdriver.Firefox(executable_path=r'D:\portable_programs\geckodriver\geckodriver.exe')
23+
# item_to_open = sys.argv[1]
24+
print('opened browser: ' + self.product_link)
25+
self.driver.get(self.product_link)
26+
except Exception as e:
27+
print('error while opening browser!', e)
28+
29+
def add_to_cart(self):
30+
try:
31+
print('looking for buying option...')
32+
button = self.driver.find_elements_by_css_selector('div.c-offerBox_addToCart a')[1]
33+
WebDriverWait(self.driver, self.wait_time).until_not(EC.visibility_of_element_located((By.CLASS_NAME, 'c-modal_container ps is-modalContVisible')))
34+
button.click()
35+
print('going to cart...')
36+
time.sleep(2)
37+
self.driver.get('https://www.mediaexpert.pl/koszyk/lista')
38+
print('cart opened!')
39+
except Exception as e:
40+
print('error while adding to cart!', e)
41+
42+
def select_delivery(self):
43+
try:
44+
print('selecting delivery...')
45+
time.sleep(1)
46+
#zaznaczenie dostawy
47+
delivery = self.driver.find_elements_by_css_selector('div.c-cart_transportWrapper input#cart_flow_list_step_transportMethod_3')[0]
48+
self.driver.execute_script("arguments[0].click();", delivery)
49+
print('delivery selected!')
50+
except Exception as e:
51+
print('error while selecting delivery!', e)
52+
53+
def select_payment(self):
54+
try:
55+
#zaznaczenie platnosci
56+
print('payment selecting...')
57+
# payment = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'div.c-cart_paymentWrapper input#cart_flow_list_step_paymentGroup_35')))
58+
print('payment selected!')
59+
except Exception as e:
60+
print('error while selecting payment!')
61+
62+
def login(self):
63+
try:
64+
go_further = WebDriverWait(self.driver, self.wait_time).until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'a.c-btn.is-primary.is-big.is-submitBtn')))
65+
self.driver.execute_script("arguments[0].click()", go_further)
66+
67+
# logowanie
68+
print('selecting login method...')
69+
without_login = WebDriverWait(self.driver, self.wait_time).until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'div.c-group_row.is-guestBtn a')))
70+
without_login.click()
71+
print('login skipped - as guest')
72+
except Exception as e:
73+
print('error while login!', e)
74+
75+
def fill_form(self, data):
76+
try:
77+
if self.is_for_company == True:
78+
print('filling company form...')
79+
self.driver.find_elements_by_css_selector('div.a-form_row.is-orderAs label')[1].click()
80+
company_name = self.driver.find_elements_by_id('cart_flow_address_step_accountAddress_company')[0]
81+
company_name.send_keys(data.get_company_name())
82+
nip = self.driver.find_elements_by_id('cart_flow_address_step_accountAddress_nip')[0]
83+
nip.send_keys(data.get_nip())
84+
else:
85+
print('filling form...')
86+
firstName = self.driver.find_elements_by_id('cart_flow_address_step_accountAddress_firstName')[0]
87+
firstName.send_keys(data.get_first_name())
88+
surname = self.driver.find_elements_by_id('cart_flow_address_step_accountAddress_lastName')[0]
89+
surname.send_keys(data.get_last_name())
90+
91+
mail = self.driver.find_elements_by_id('cart_flow_address_step_accountAddress_email')[0]
92+
mail.send_keys(data.get_mail())
93+
street = self.driver.find_elements_by_id('cart_flow_address_step_accountAddress_street')[0]
94+
street.send_keys(data.get_street())
95+
house = self.driver.find_elements_by_id('cart_flow_address_step_accountAddress_houseNumber')[0]
96+
house.send_keys(data.get_house_number())
97+
apartment = self.driver.find_elements_by_id('cart_flow_address_step_accountAddress_apartmentNumber')[0]
98+
apartment.send_keys(data.get_apartment_number())
99+
postcode = self.driver.find_elements_by_id('cart_flow_address_step_accountAddress_postcode')[0]
100+
postcode.send_keys(data.get_postcode())
101+
city = self.driver.find_elements_by_id('cart_flow_address_step_accountAddress_city')[0] ## error
102+
city.send_keys('')
103+
phone = self.driver.find_elements_by_id('cart_flow_address_step_accountAddress_phone')[0]
104+
phone.send_keys(data.get_phone_number())
105+
check = self.driver.find_elements_by_id('cart_flow_address_step_consentForm_consent_332')[0]
106+
self.driver.execute_script("arguments[0].click();", check)
107+
print('form filled!')
108+
109+
# time.sleep(1) #retrying selecting city
110+
# city = driver.find_elements_by_id('cart_flow_address_step_accountAddress_city')[0] ## error
111+
# city.send_keys('Katowice')
112+
time.sleep(1)
113+
except Exception as e:
114+
print('error while filling form!', e)
115+
116+
def go_to_summary(self):
117+
try:
118+
#przejscie dalej do kalendarza
119+
# driver.find_elements_by_css_selector('div.c-calendar_contentRow a')[0]
120+
go_further_calendar = WebDriverWait(self.driver, self.wait_time).until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'button.c-btn.is-primary.is-big')))
121+
self.driver.execute_script("arguments[0].click()", go_further_calendar)
122+
print('date chosen!')
123+
124+
#przejscie dalej do podsumowania
125+
go_further = WebDriverWait(self.driver, self.wait_time).until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'a.c-btn.is-primary.is-big')))
126+
self.driver.execute_script("arguments[0].click()", go_further)
127+
except Exception as e:
128+
print('error while going to summary!', e)
129+
130+
def buy(self):
131+
try:
132+
print("started procedure!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
133+
self.open_browser()
134+
self.add_to_cart()
135+
self.select_delivery()
136+
self.login()
137+
self.fill_form(self.data)
138+
self.go_to_summary()
139+
print('done!')
140+
return True
141+
except:
142+
return False
143+
finally:
144+
print('ended procedure...')
145+
# driver.quit()

src/settings.py

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import json
2+
from types import SimpleNamespace
3+
4+
class Settings:
5+
def __init__(self, file_name):
6+
print('opening settings file: ' + file_name + '...')
7+
self.load(file_name)
8+
x = 'company' if self.is_for_company() else 'person'
9+
print('settings loaded for: ' + x)
10+
print('refresh rate: ' + str(self.get_interval()) + 's')
11+
print('looking for: ' + self.get_name() + '...')
12+
13+
def load(self, file_name):
14+
try:
15+
with open(file_name) as f:
16+
text = f.read()
17+
self.data = json.loads(text, object_hook=lambda d: SimpleNamespace(**d))
18+
except Exception as e:
19+
print('error while opening settings: ', e)
20+
21+
def get_link(self):
22+
return self.data.product_link
23+
24+
def get_name(self):
25+
return self.data.product_link.split('/')[-1]
26+
27+
def get_interval(self):
28+
return self.data.check_time_interval
29+
30+
def get_wait_for_element(self):
31+
return self.data.wait_time
32+
33+
def get_driver_path(self):
34+
return self.data.geckodriver_path
35+
36+
def is_for_company(self):
37+
return self.data.is_company_purchase
38+
39+
def get_nip(self):
40+
return self.data.company_data.nip
41+
42+
def get_company_name(self):
43+
return self.data.company_data.company_name
44+
45+
def get_first_name(self):
46+
return self.data.personal_data.first_name
47+
48+
def get_last_name(self):
49+
return self.data.personal_data.last_name
50+
51+
def get_mail(self):
52+
if self.is_for_company() == True:
53+
return self.data.company_data.mail
54+
else:
55+
return self.data.personal_data.mail
56+
57+
def get_street(self):
58+
if self.is_for_company() == True:
59+
return self.data.company_data.street
60+
else:
61+
return self.data.personal_data.street
62+
63+
def get_house_number(self):
64+
if self.is_for_company() == True:
65+
return self.data.company_data.house_number
66+
else:
67+
return self.data.personal_data.house_number
68+
69+
def get_apartment_number(self):
70+
if self.is_for_company() == True:
71+
return self.data.company_data.apartment_number
72+
else:
73+
return self.data.personal_data.apartment_number
74+
75+
def get_postcode(self):
76+
if self.is_for_company() == True:
77+
return self.data.company_data.postcode
78+
else:
79+
return self.data.personal_data.postcode
80+
81+
def get_city(self):
82+
if self.is_for_company() == True:
83+
return self.data.company_data.city
84+
else:
85+
return self.data.personal_data.city
86+
87+
def get_phone_number(self):
88+
if self.is_for_company() == True:
89+
return self.data.company_data.phone_number
90+
else:
91+
return self.data.personal_data.phone_number

0 commit comments

Comments
 (0)