Merge pull request #3 from j4rj4r/fix-use-all-categories

Fix - Use all categories
This commit is contained in:
Jarjar 2023-02-07 22:21:18 +01:00 committed by GitHub
commit f8192e0011
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 52 additions and 39 deletions

View File

@ -1,7 +1,10 @@
./data/logs/*.logs ./data/logs/*.logs
./data/data.db ./data/data.db
./data/profiles/prof_*
.vscode .vscode
.gitignore .gitignore
.idea/ .idea/
./__pycache__/ ./__pycache__/
./GlobalExambBot/__pycache__/ ./GlobalExambBot/__pycache__/
.git
*.md

View File

@ -21,11 +21,11 @@ class Sheets:
WebDriverWait(self.driver, 15).until(ec.visibility_of_element_located((By.XPATH, self.pagecard_xpath))) WebDriverWait(self.driver, 15).until(ec.visibility_of_element_located((By.XPATH, self.pagecard_xpath)))
page_cards = self.driver.find_elements(by=By.XPATH, value=self.pagecard_xpath) page_cards = self.driver.find_elements(by=By.XPATH, value=self.pagecard_xpath)
card_list = [] card_list = []
for card in page_cards : for card in page_cards :
if not self.manageSheets.link_exist(card.get_attribute('href')): if not self.manageSheets.link_exist(card.get_attribute('href')):
card_list.append(card) card_list.append(card)
return card_list return card_list
def watch(self, Sheets_el): def watch(self, Sheets_el):
self.actions.move_to_element(Sheets_el).click(Sheets_el).perform() self.actions.move_to_element(Sheets_el).click(Sheets_el).perform()
WebDriverWait(self.driver, 15).until(ec.visibility_of_element_located((By.XPATH, self.Sheetscard_xpath))) WebDriverWait(self.driver, 15).until(ec.visibility_of_element_located((By.XPATH, self.Sheetscard_xpath)))

View File

@ -1,5 +1,6 @@
import logging import logging
import os import os
import sys
from GlobalExamBot.helpers import TypeInField, element_exists, wait_between from GlobalExamBot.helpers import TypeInField, element_exists, wait_between
from GlobalExamBot.Sheets import Sheets from GlobalExamBot.Sheets import Sheets
@ -11,6 +12,7 @@ from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
class Bot: class Bot:
def __init__(self, driver, action, configuration): def __init__(self, driver, action, configuration):
self.driver = driver self.driver = driver
self.actions = action self.actions = action
@ -18,7 +20,7 @@ class Bot:
self.email_xpath = '//input[@name="email"]' self.email_xpath = '//input[@name="email"]'
self.password_xpath = '//input[@name="password"]' self.password_xpath = '//input[@name="password"]'
self.index = 0 self.index = 0
self.scrollcount = 0 self.catindex = 0
self.categories = ['https://exam.global-exam.com/library/study-sheets/categories/grammar', self.categories = ['https://exam.global-exam.com/library/study-sheets/categories/grammar',
'https://exam.global-exam.com/library/study-sheets/categories/language-functions', 'https://exam.global-exam.com/library/study-sheets/categories/language-functions',
'https://exam.global-exam.com/library/study-sheets/categories/vocabulary'] 'https://exam.global-exam.com/library/study-sheets/categories/vocabulary']
@ -33,7 +35,7 @@ class Bot:
password_el.send_keys(Keys.RETURN) password_el.send_keys(Keys.RETURN)
def run(self): def run(self):
profile = f'prof_{self.configuration.username}' profile = f'prof_{self.configuration.username}'
if not os.path.exists(f'./Profiles/{profile}'): if not os.path.exists(f'./Profiles/{profile}'):
@ -49,20 +51,17 @@ class Bot:
Sheets_action = Sheets(self.driver, self.actions, self.configuration) Sheets_action = Sheets(self.driver, self.actions, self.configuration)
while True: while True:
self.driver.get('https://exam.global-exam.com/library/study-sheets/categories/grammar') self.driver.get(self.categories[self.catindex])
Sheets_list = Sheets_action.search() Sheets_list = Sheets_action.search()
if Sheets_list : if Sheets_list :
logging.info(f'Sheets n°{ self.index }') logging.info(f'Sheets n°{ self.index }')
Sheets_action.watch(Sheets_list[0]) Sheets_action.watch(Sheets_list[0])
self.index +=1 self.index +=1
self.scrollcount = 0
wait_between(3,10) wait_between(3,10)
else: else:
logging.info('All visible Sheets have already been read. Need to scroll down ...') if self.catindex != len(self.categories) - 1 :
self.driver.execute_script(f"window.scrollTo(0, document.body.scrollHeight)") logging.info('All visible Sheets have already been read. Use of the next category.')
self.scrollcount += 1 self.catindex += 1
wait_between(5,15) else:
if self.scrollcount > 10: logging.info('No category available.')
logging.info('End of page or network error.') sys.exit(1)
self.scrollcount = 0
logging.info(self.driver.get_log('browser'))

View File

@ -1,4 +1,4 @@
def init(): def init():
global VERSION, APP_NAME global VERSION, APP_NAME
APP_NAME = 'GlobalExamBot' APP_NAME = 'GlobalExamBot'
VERSION = '1.0.0' VERSION = '1.0.0'

View File

@ -1,6 +1,9 @@
import sqlite3 import sqlite3
class Database: class Database:
"""
Database management
"""
def __init__(self, database_link='./data/data.db'): def __init__(self, database_link='./data/data.db'):
""" """
Database constructor Database constructor
@ -18,7 +21,7 @@ class Database:
c.execute('''INSERT INTO sheet_links (link) VALUES (:link);''', (link,)) c.execute('''INSERT INTO sheet_links (link) VALUES (:link);''', (link,))
c.close() c.close()
connection.commit() connection.commit()
def link_exist(self, link): def link_exist(self, link):
""" """
Returns true if the link exists in the database. Returns true if the link exists in the database.
@ -45,4 +48,4 @@ def create_table_sheets():
c.execute('''CREATE TABLE IF NOT EXISTS sheet_links c.execute('''CREATE TABLE IF NOT EXISTS sheet_links
(id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, link text);''') (id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, link text);''')
c.close() c.close()
connection.commit() connection.commit()

View File

@ -3,6 +3,9 @@ from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.options import Options
class Driver: class Driver:
"""
Browser management
"""
def __init__(self, profile): def __init__(self, profile):
self.profile = profile self.profile = profile
self.chrome_options = None self.chrome_options = None
@ -10,6 +13,9 @@ class Driver:
self.action = None self.action = None
def setup(self, log_path='./data/logs/', headless=True): def setup(self, log_path='./data/logs/', headless=True):
"""
Browser configuration
"""
self.chrome_options = Options() self.chrome_options = Options()
# Anti bot detection # Anti bot detection
@ -22,7 +28,7 @@ class Driver:
# Maximize Browser # Maximize Browser
self.chrome_options.add_argument('--start-maximized') self.chrome_options.add_argument('--start-maximized')
# Headless Mode # Headless Mode
if headless: if headless:
self.chrome_options.add_argument('--headless') self.chrome_options.add_argument('--headless')
@ -44,7 +50,6 @@ class Driver:
self.chrome_options.add_argument("--disable-low-res-tiling") self.chrome_options.add_argument("--disable-low-res-tiling")
self.chrome_options.add_argument("--log-level=3") self.chrome_options.add_argument("--log-level=3")
self.chrome_options.add_argument("--silent") self.chrome_options.add_argument("--silent")
# Disable save password # Disable save password
prefs = {'credentials_enable_service': False, prefs = {'credentials_enable_service': False,
@ -54,12 +59,12 @@ class Driver:
# Set profile # Set profile
self.chrome_options.add_argument(f'user-data-dir=./data/profiles/{self.profile}') self.chrome_options.add_argument(f'user-data-dir=./data/profiles/{self.profile}')
self.driver = webdriver.Chrome(f'./ChromeDriver/chromedriver',options=self.chrome_options, service_args=[f'--log-path={log_path}ChromeDriver.log']) self.driver = webdriver.Chrome('./ChromeDriver/chromedriver',options=self.chrome_options, service_args=[f'--log-path={log_path}ChromeDriver.log'])
self.action = ActionChains(self.driver) self.action = ActionChains(self.driver)
return self.driver, self.action return self.driver, self.action
def get_driver(self): def get_driver(self):
return self.driver return self.driver
def get_action(self): def get_action(self):
return self.action return self.action

View File

@ -38,7 +38,7 @@ class Helpers:
def load_configuration(self): def load_configuration(self):
""" """
this method allows you to load arguments. this method allows you to load arguments.
:return: args :return: args
""" """
header() header()
# Load all configuration variables # Load all configuration variables
@ -50,10 +50,13 @@ class Helpers:
return args return args
def logging_configuration(self, logging_level=logging.INFO, filename='data/logs/bot_globalexam.log'): def logging_configuration(self, logging_level=logging.INFO, filename='data/logs/bot_globalexam.log'):
"""
Log configuration
"""
logging.basicConfig(filename=filename, logging.basicConfig(filename=filename,
level=logging_level, level=logging_level,
format='%(asctime)s - %(levelname)s - %(message)s') format='%(asctime)s - %(levelname)s - %(message)s')
root_logger = logging.getLogger() root_logger = logging.getLogger()
root_logger.setLevel(logging_level) root_logger.setLevel(logging_level)
@ -74,26 +77,26 @@ def header():
logging.info('==\t version : ' + const.VERSION + ' \t==') logging.info('==\t version : ' + const.VERSION + ' \t==')
logging.info('==\t=============================================================\t==') logging.info('==\t=============================================================\t==')
def wait_between( min, max): def wait_between( minimum, maximum):
""" """
Wait random time in second beetween min and max seconds, to have an not linear behavior and be more human. Wait random time in second beetween min and max seconds,
to have an not linear behavior and be more human.
""" """
rand=uniform(min, max) rand=uniform(minimum, maximum)
sleep(rand) sleep(rand)
def TypeInField(element, xpath, myValue): def TypeInField(element, xpath, value):
"""Type in a field""" """Type in a field"""
val = myValue
elem = element.find_element(by=By.XPATH, value=xpath) elem = element.find_element(by=By.XPATH, value=xpath)
for i in range(len(val)): for ele in enumerate(value):
elem.send_keys(val[i]) elem.send_keys(ele[1])
wait_between(0.2, 0.4) wait_between(0.2, 0.4)
wait_between(0.4, 0.7) wait_between(0.4, 0.7)
def element_exists(xpath, element, by=By.XPATH): def element_exists(xpath, element, by=By.XPATH):
""" """
Check if an element exist Check if an element exist
:return: Boolean :return: Boolean
""" """
try: try:
@ -101,4 +104,4 @@ def element_exists(xpath, element, by=By.XPATH):
element.find_element(by=by, value=xpath) element.find_element(by=by, value=xpath)
except: except:
return False return False
return True return True

View File

@ -8,14 +8,14 @@ from GlobalExamBot.database import create_table_sheets
from GlobalExamBot.driver import Driver from GlobalExamBot.driver import Driver
from GlobalExamBot.bot import Bot from GlobalExamBot.bot import Bot
def main(): def main():
try: try:
helpers = Helpers() helpers = Helpers()
# Configuration of the logging library # Configuration of the logging library
helpers.logging_configuration() helpers.logging_configuration()
# Load all configuration variables # Load all configuration variables
config = helpers.load_configuration() config = helpers.load_configuration()
@ -24,7 +24,7 @@ def main():
create_table_sheets() create_table_sheets()
profile = f'prof_{config.username}' profile = f'prof_{config.username}'
logging.info(f'Username : {config.username}') logging.info(f'Username : {config.username}')
# Initialize driver and actions # Initialize driver and actions
@ -46,4 +46,4 @@ def main():
sys.exit(1) sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":
main() main()