How to use row_xpath method in pom

Best Python code snippet using pom_python

jobcan.py

Source:jobcan.py Github

copy

Full Screen

1# coding: utf-82from selenium import webdriver3from selenium.webdriver.support.ui import Select4from selenium.common.exceptions import NoSuchElementException5from selenium.webdriver.common.keys import Keys6import time7import datetime8# utility9def checkbox_setvalue(checkbox, value, toggle='click'):10 value = bool(value)11 if checkbox.is_selected() == value:12 return False13 if toggle.lower() == 'click':14 checkbox.click()15 elif toggle.lower() == 'enter':16 checkbox.send_keys(Keys.ENTER)17 elif toggle.lower() == 'space':18 checkbox.send_keys(Keys.SPACE)19# Main classes20class Jobcan:21 def __init__(self, user_email=None, user_password=None, chromedriver_path=None):22 if (user_email and user_password) is None:23 with open('./setting') as f:24 user_email = user_email or f.readline().strip()25 user_password = user_password or f.readline().strip()26 chromedriver_path = chromedriver_path or f.readline().strip() or 'chromedriver'27 self.user_email = user_email28 self.user_password = user_password29 self.chromedriver_path = chromedriver_path30 if self.chromedriver_path is not None:31 self.driver = webdriver.Chrome(self.chromedriver_path)32 else:33 self.driver = webdriver.Chrome()34 self.login()35 @staticmethod36 def setting_file(filepath):37 with open(filepath) as f:38 user_email = f.readline().strip()39 user_password = f.readline().strip()40 chromedriver_path = f.readline().strip() or 'chromedriver'41 return Jobcan(user_email, user_password, chromedriver_path)42 def login(self):43 self.driver.get('https://id.jobcan.jp/users/sign_in')44 email = self.driver.find_element_by_id('user_email')45 email.clear()46 email.send_keys(self.user_email)47 password = self.driver.find_element_by_id('user_password')48 password.clear()49 password.send_keys(self.user_password)50 self.driver.find_element_by_name('commit').click()51 self.driver.get('https://ssl.jobcan.jp/jbcoauth/login')52 def close(self):53 if self.driver is not None:54 self.driver.close()55 def move(self, dst):56 if self.driver.current_url == dst:57 return58 else:59 self.driver.get(dst)60 time.sleep(1)61 if self.driver.current_url.startswith('https://id.jobcan.jp/users/sign_in'): # リログ62 self.login()63 self.driver.get(dst)64 time.sleep(1)65 return66 def start_job(self, adit_group_text=None, yakin=False):67 """68 勤務開始の打刻をします。69 未出勤/退室中 のとき, 入室70 勤務中のとき, 71 打刻場所と勤務場所が異なる場合, 移動72 打刻場所と勤務場所が同一の場合, 何もしない73 打刻場所を指定しない場合, 何もしない74 return: (時刻:'hh:mm', jobcanに打刻したか?:True/False)75 """76 status = False77 if not adit_group_text is None:78 adit_group_text = str(adit_group_text)79 if yakin:80 status = self.get_status_table('yesterday')81 else:82 status = self.get_status_table()83 self.move('https://ssl.jobcan.jp/employee')84 checkbox_setvalue(self.driver.find_element_by_id('is_yakin'), yakin)85 # 場所の選択86 if adit_group_text is not None:87 if self.driver.find_element_by_id('working_status').text == '勤務中': # 勤務中: 勤務場所変更か何もしない88 if status and status[-1]['打刻場所'] == adit_group_text:89 print('既に同一地点で勤務中です')90 return self.get_time(), False91 else:92 print('勤務場所を変更します')93 else:94 print('勤務開始します')95 Select(self.driver.find_element_by_css_selector('#adit_group_id')).select_by_visible_text(adit_group_text)96 else:97 if self.driver.find_element_by_id('working_status').text == '勤務中': # 勤務中: 何もしない98 print('勤務中です')99 return self.get_time(), False100 else:101 print('勤務を開始します')102 # 時刻の取得103 # t = self.get_time()104 # 出勤105 self.driver.find_element_by_id('adit-button-push').click()106 time.sleep(5)107 t = self.get_status_table()[-1]['時刻']108 return t, True109 def end_job(self, yakin=False):110 """111 勤務終了の打刻をします。112 未出勤/退室中 のとき, 何もしない113 勤務中のとき, 勤務場所で打刻をし, 退室114 return: (時刻:'hh:mm', jobcanに打刻したか?:True/False)115 """116 if yakin:117 status = self.get_status_table('yesterday')118 else:119 status = self.get_status_table()120 self.move('https://ssl.jobcan.jp/employee')121 checkbox_setvalue(self.driver.find_element_by_id('is_yakin'), yakin)122 if status:123 adit_group_text = status[-1]['打刻場所']124 Select(self.driver.find_element_by_css_selector('#adit_group_id')).select_by_visible_text(adit_group_text)125 if self.driver.find_element_by_id('working_status').text != '勤務中':126 print('勤務中ではありません')127 return self.get_time(), False128 #t = self.get_time()129 self.driver.find_element_by_id('adit-button-push').click()130 time.sleep(5)131 t = self.get_status_table()[-1]['時刻']132 return t, True133 def get_time(self):134 prev = self.driver.current_url135 self.move('https://ssl.jobcan.jp/employee')136 for i in range(10):137 t = self.driver.find_element_by_id('clock').text.split(':')138 if len(t) == 3:139 h, m, s = map(int, t)140 if (h, m, s) != (0, 0, 0):141 s -= i142 m += (s // 60)143 h += (m // 60)144 return '{:0>2}:{:0>2}'.format(h, m)145 time.sleep(1)146 raise AssertionError147 def get_status_table(self, day='today', fmt='%Y/%m/%d'):148 day = day.lower()149 self.move('https://ssl.jobcan.jp/employee/adit/modify/')150 if day=='today':151 pass152 else:153 if day=='yesterday':154 iyear = int(Select(self.driver.find_element_by_name('year')).first_selected_option.text)155 imonth = int(Select(self.driver.find_element_by_name('month')).first_selected_option.text)156 iday = int(Select(self.driver.find_element_by_name('day')).first_selected_option.text)157 date = datetime.date(iyear, imonth, iday) - datetime.timedelta(days=1)158 else:159 date = datetime.datetime.strptime(day, fmt).date()160 # set date161 self.move('https://ssl.jobcan.jp/employee/adit/modify?year={}&month={}&day={}'.format(date.year, date.month, date.day))162 try:163 rows = len(self.driver.find_element_by_xpath('//*[@id="logs-table"]/div/table/tbody').find_elements_by_tag_name('tr'))164 except NoSuchElementException:165 return []166 ret = []167 for i in range(1, rows):168 row_xpath = '//*[@id="logs-table"]/div/table/tbody/tr[{}]/'.format(i+1)169 d = {}170 d['打刻区分'] = self.driver.find_element_by_xpath(row_xpath + ' td[1]').text171 d['時刻'] = self.driver.find_element_by_xpath(row_xpath + 'td[2]').text172 d['打刻方法'] = self.driver.find_element_by_xpath(row_xpath + 'td[3]').text173 d['打刻場所'] = self.driver.find_element_by_xpath(row_xpath + 'td[4]').text174 d['打刻備考等'] = self.driver.find_element_by_id('edit-reason-{}_text'.format(i)).text175 ret.append(d)176 return ret177 def get_adit_group(self):178 self.move('https://ssl.jobcan.jp/employee')179 return [s.text for s in Select(self.driver.find_element_by_css_selector('#adit_group_id')).options]180 def __del__(self):181 self.close()182 # 工数管理183 def _mh_set_year_month(self, year, month):184 year = str(year)185 s = Select(self.driver.find_element_by_name('year'))186 if not s.first_selected_option.text == year:187 s.select_by_visible_text(year)188 month = str(month)189 if len(month) == 1:190 month = '0' + month191 s = Select(self.driver.find_element_by_name('month'))192 def _mh_open_daily_window(self, year, month, day):193 self._mh_set_year_month(year, month)194 self.driver.find_element_by_xpath(195 '//*[@id="search-result"]/table/tbody/tr[{}]/td[4]/div'.format(int(day))).click()196 time.sleep(5)197 def _mh_daily_close_window(self):198 self.driver.find_element_by_id('menu-close').send_keys(Keys.ENTER)199 def _mh_daily_save_close_window(self):200 self.driver.find_element_by_id('save').send_keys(Keys.ENTER)201 def _mh_daily_get_report(self): # daily-windowを開いた状態で呼ぶメソッド202 rows = len(self.driver.find_element_by_xpath('//*[@id="edit-menu-contents"]/table/tbody').find_elements_by_tag_name('tr'))203 ret = []204 for i in range(2, rows+1):205 row_xpath = '//*[@id="edit-menu-contents"]/table/tbody/tr[{}]/'.format(i)206 d = {}207 d['プロジェクト'] = Select(self.driver.find_element_by_xpath(row_xpath + 'td[2]/select')).first_selected_option.text208 d['タスク'] = Select(self.driver.find_element_by_xpath(row_xpath + 'td[3]/select')).first_selected_option.text209 d['工数'] = self.driver.find_element_by_xpath(row_xpath + 'td[4]/input[1]').get_attribute('value')210 ret.append(d)211 return ret212 def _mh_daily_append_record_tail(self, project_name, task_name, worktime_hour, worktime_minute):213 rows = len(self.driver.find_element_by_xpath(214 '//*[@id="edit-menu-contents"]/table/tbody').find_elements_by_tag_name('tr'))215 if rows == 1:216 xpath = '//*[@id="edit-menu-contents"]/table/tbody/tr[1]/td[5]/span'217 else:218 xpath = '//*[@id="edit-menu-contents"]/table/tbody/tr[{}]/td[5]/span[1]'.format(rows)219 self.driver.find_element_by_xpath(xpath).click()220 row_xpath = '//*[@id="edit-menu-contents"]/table/tbody/tr[{}]/'.format(rows + 1)221 Select(self.driver.find_element_by_xpath(row_xpath + 'td[2]/select')).select_by_visible_text(project_name)222 Select(self.driver.find_element_by_xpath(row_xpath + 'td[3]/select')).select_by_visible_text(task_name)223 worktime_minute += worktime_hour * 60224 worktime_hour = worktime_minute // 60225 worktime_min = worktime_minute % 60226 self.driver.find_element_by_xpath(row_xpath + 'td[4]/input[1]').send_keys('{}:{}'.format(worktime_hour, worktime_min))227 def _mh_daily_add_record(self, project_name, task_name, worktime_hour, worktime_minute): # 時間追加用メソッド228 rows = len(self.driver.find_element_by_xpath(229 '//*[@id="edit-menu-contents"]/table/tbody').find_elements_by_tag_name('tr'))230 for i in range(2, rows+1):231 row_xpath = '//*[@id="edit-menu-contents"]/table/tbody/tr[{}]/'.format(i)232 if Select(self.driver.find_element_by_xpath(row_xpath + 'td[2]/select')).first_selected_option.text== project_name:233 if Select(self.driver.find_element_by_xpath(row_xpath + 'td[3]/select')).first_selected_option.text== task_name:234 input_ = self.driver.find_element_by_xpath(row_xpath + 'td[4]/input[1]')235 hour, min = input_.get_attribute('value').split(':')236 minutes = int(min) + 60 * int(hour) + worktime_minute + int(60 * worktime_hour)237 input_.clear()238 input_.send_keys('{}:{}'.format(minutes//60, minutes%60))239 return240 self._mh_daily_append_record_tail(project_name, task_name, worktime_hour, worktime_minute)241 def _mh_daily_write_record(self, project_name, task_name, worktime_hour, worktime_minute): # 上書き用メソッド242 rows = len(self.driver.find_element_by_xpath(243 '//*[@id="edit-menu-contents"]/table/tbody').find_elements_by_tag_name('tr'))244 for i in range(2, rows+1):245 row_xpath = '//*[@id="edit-menu-contents"]/table/tbody/tr[{}]/'.format(i)246 if Select(self.driver.find_element_by_xpath(row_xpath + 'td[2]/select')).first_selected_option.text== project_name:247 if Select(self.driver.find_element_by_xpath(row_xpath + 'td[3]/select')).first_selected_option.text== task_name:248 input_ = self.driver.find_element_by_xpath(row_xpath + 'td[4]/input[1]')249 minutes = worktime_minute + int(60 * worktime_hour)250 input_.clear()251 input_.send_keys('{}:{}'.format(minutes//60, minutes%60))252 return253 self._mh_daily_append_record_tail(project_name, task_name, worktime_hour, worktime_minute)254 def add_man_hour(self, project_name, task_name, year, month, day, worktime_hour, worktime_minute):255 self.move('https://ssl.jobcan.jp/employee/man-hour-manage')256 self._mh_open_daily_window(year, month, day)257 self._mh_daily_add_record(project_name, task_name, worktime_hour, worktime_minute)258 self._mh_daily_save_close_window()259 def get_man_hour(self, year, month, day):260 self.move('https://ssl.jobcan.jp/employee/man-hour-manage')261 self._mh_open_daily_window(year, month, day)262 ret = self._mh_daily_get_report()263 self._mh_daily_close_window()264 return ret265 def get_projects_and_tasks(self):266 date = datetime.date.today()267 self.move('https://ssl.jobcan.jp/employee/man-hour-manage')268 self._mh_open_daily_window(date.year, date.month, date.day)269 rows = len(self.driver.find_element_by_xpath(270 '//*[@id="edit-menu-contents"]/table/tbody').find_elements_by_tag_name('tr'))271 if rows == 1:272 xpath = '//*[@id="edit-menu-contents"]/table/tbody/tr[1]/td[5]/span'273 else:274 xpath = '//*[@id="edit-menu-contents"]/table/tbody/tr[{}]/td[5]/span[1]'.format(rows)275 self.driver.find_element_by_xpath(xpath).click()276 row_xpath = '//*[@id="edit-menu-contents"]/table/tbody/tr[{}]/'.format(rows + 1)277 projects = [s.text for s in Select(self.driver.find_element_by_xpath(row_xpath + 'td[2]/select')).options]278 ret = {}279 for project in projects:280 Select(self.driver.find_element_by_xpath(row_xpath + 'td[2]/select')).select_by_visible_text(project)281 tasks = tuple(s.text for s in Select(self.driver.find_element_by_xpath(row_xpath + 'td[3]/select')).options)282 ret[project] = tasks283 self._mh_daily_close_window()...

Full Screen

Full Screen

onvista.py

Source:onvista.py Github

copy

Full Screen

1import lxml.html2import re3from decimal import Decimal4from stockanalyser.mymoney import Money5import logging6from stockanalyser.data_source import common7logger = logging.getLogger(__name__)8class ParsingError(Exception):9 pass10def is_number(txt):11 try:12 float(txt)13 return True14 except (ValueError, TypeError):15 return False16class OnvistaScraper(object):17 def __init__(self, url):18 self.overview_url = url19 self.fundamental_url = self._build_fundamental_url(url)20 self.fundamental_etree = None21 self.fetch_fundamental_webpage()22 self.fetch_overview_webpage()23 def _build_fundamental_url(self, url):24 spl = url.split("/")25 spl.insert(4, "fundamental")26 return "/".join(spl)27 def fetch_fundamental_webpage(self):28 self.fundamental_etree = common.url_to_etree(self.fundamental_url)29 def fetch_overview_webpage(self):30 self.overview_etree = common.url_to_etree(self.overview_url)31 def _get_analyst_rating(self, xpath):32 res = self.overview_etree.xpath(xpath)33 if not res:34 return None35 v = int(res[0].strip())36 return v37 def analyst_ratings(self):38 buy_xpath = ('.//*[@id="AggregatedAnalysesTabAction"]/div/article/'39 'div/table/tbody/tr[1]/td[2]/text()')40 hold_xpath = ('.//*[@id="AggregatedAnalysesTabAction"]/div/article/'41 'div/table/tbody/tr[2]/td[2]/text()')42 sell_xpath = ('.//*[@id="AggregatedAnalysesTabAction"]/div/article/'43 'div/table/tbody/tr[3]/td[2]/text()')44 buy = self._get_analyst_rating(buy_xpath)45 hold = self._get_analyst_rating(hold_xpath)46 sell = self._get_analyst_rating(sell_xpath)47 return (buy, hold, sell)48 def _get_table_header(self, header):49 # onvista uses 2 different presentation for the year:50 # "18/19e 17/18e 16/17e 15/16" and51 # "2019e 2018e 2017e 2016e"52 theader = []53 for r in header:54 v = r.text.lower().strip()55 if not len(v):56 continue57 # handle presentation of years as58 # "18/19e 17/18e 16/17e 15/16", convert them to the59 # YYYY (eg 2018) format60 if "/" in v:61 v = "20" + v.split("/")[1]62 # remove the "e" for estimated from year endings63 if re.match("\d+e", v):64 v = int(v[:-1])65 elif is_number(v):66 v = int(v)67 theader.append(v)68 return theader69 def _normalize_number(self, string):70 v = string.lower().strip()71 if v == "-":72 return None73 # replace german decimal seperator "," with "."74 v = v.replace(",", ".")75 v = v.replace("%", "")76 return v77 def _extract_from_table(self, table_xpath, table_header, row_xpath,78 row_header, is_money=False):79 res = self.fundamental_etree.findall(table_xpath)80 theader = self._get_table_header(res)81 if theader[0] != table_header:82 raise ParsingError("Unexpected table header: '%s'" % theader[0])83 res = self.fundamental_etree.findall(row_xpath)84 rows = []85 for r in res:86 v = self._normalize_number(r.text)87 if v is not None and not len(v):88 continue89 elif is_number(v):90 if is_money:91 v = Money(Decimal(v), "EUR")92 else:93 v = float(v)94 rows.append(v)95 if rows[0] != row_header:96 raise ParsingError("Unexpected 1. row header: '%s' != '%s'" %97 (rows[0], row_header))98 if len(theader) != len(rows):99 raise ParsingError("Parsing error, table header contains more"100 " elements than rows:"101 "'%s' vs '%s'" % (theader, rows))102 result = {}103 for i in range(len(rows)):104 if theader[i] == table_header:105 continue106 result[theader[i]] = rows[i]107 logger.debug("Extracted '%s' from onvista: %s" % (row_header, result))108 return result109 def eps(self):110 table_xpath = ('.//*[@id="ONVISTA"]/div[1]/div[1]/div[1]/'111 'article/article/div/table[1]/thead/tr/')112 row_xpath = ('.//*[@id="ONVISTA"]/div[1]/div[1]/div[1]/'113 'article/article/div/table[1]/tbody/tr[1]/')114 return self._extract_from_table(table_xpath, "gewinn", row_xpath,115 "gewinn pro aktie in eur", True)116 def ebit_margin(self):117 table_xpath = ('.//*[@id="ONVISTA"]/div[1]/div[1]/div[1]/'118 'article/article/div/table[8]/thead/tr/')119 row_xpath = ('.//*[@id="ONVISTA"]/div[1]/div[1]/div[1]/'120 'article/article/div/table[8]/tbody/tr[2]/')121 return self._extract_from_table(table_xpath, "rentabilität", row_xpath,122 "ebit-marge")123 def equity_ratio(self):124 table_xpath = ('.//*[@id="ONVISTA"]/div[1]/div[1]/div[1]/'125 'article/article/div/table[6]/thead/tr/')126 row_xpath = ('.//*[@id="ONVISTA"]/div[1]/div[1]/div[1]/'127 'article/article/div/table[6]/tbody/tr[2]/')128 return self._extract_from_table(table_xpath, "bilanz", row_xpath,129 "eigenkapitalquote")130 def roe(self):131 table_xpath = ('.//*[@id="ONVISTA"]/div[1]/div[1]/div[1]/'132 'article/article/div/table[8]/thead/tr/')133 row_xpath = ('.//*[@id="ONVISTA"]/div[1]/div[1]/div[1]/'134 'article/article/div/table[8]/tbody/tr[4]/')135 return self._extract_from_table(table_xpath, "rentabilität", row_xpath,136 "eigenkapitalrendite")137if __name__ == "__main__":138 logging.basicConfig(level=logging.DEBUG)139 o = OnvistaScraper("http://www.onvista.de/aktien/Bayer-Aktie-DE000BAY0017")140 print(o.analyst_ratings())141 print("ROE: %s" % o.roe())142 print("EPS: %s" % o.eps())143 print("EBIT-MARGIN: %s" % o.ebit_margin())...

Full Screen

Full Screen

utils.py

Source:utils.py Github

copy

Full Screen

1import selenium2from selenium.webdriver.common.by import By3LATENCY = 0.54def attrs_to_dict(attributes: str):5 attrs_dict = dict()6 for keyval in attributes.split(';'):7 t = keyval.split(':')8 if len(t) > 1:9 key = t[0].strip()10 val = t[1].strip()11 attrs_dict[key] = val12 return attrs_dict13def find_row(ctx, table_xpath: str) -> bool:14 row = 215 row_xpath = table_xpath + '/tbody/tr[{}]/td[{}]'16 try:17 while True:18 n = ctx.driver.find_element(By.XPATH, row_xpath.format(row, 1)).text19 p = ctx.driver.find_element(By.XPATH, row_xpath.format(row, 2)).text.split('.')[0]20 if n == ctx.name and p == ctx.price:21 break22 row += 123 except selenium.common.exceptions.NoSuchElementException:24 return False...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run pom automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful