def select_empty_court_and_time(driver, mouse, cfg, time, logger=None): """ 表示された空きコートを選択する """ global http_req_num # 待機時間を設定する wait = WebDriverWait(driver, 10) # 検索ページがすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) # 検索結果をHTMLソースとしてオブジェクトに保存する html = driver.page_source # 表示された空きコートの空き時間帯と空き状況カレンダーの空き時間帯の行数を取得する (_time, _row_num) = get_empty_time_and_row_number(html, cfg, time, logger=logger) # 空きコートの空き時間帯のリンクをクリックする _xpath = f'//*[@id="pageTop"]/article/section[3]/article/section[2]/div[2]/div/table/tbody/tr[{_row_num}]/td[2]/form/a' #logger.debug(f'xpath for click: {_xpath}') driver.find_element(By.XPATH, f'{_xpath}').click() http_req_num += 1 wait.until(EC.title_contains("随時予約(確認)|八王子市施設予約システム")) # 画面のtitleが予約登録画面であることを確認する assert '随時予約(確認)|八王子市施設予約システム' in driver.title return driver, mouse
def selenium_post_conditions(driver, date_list, reserves_list, cfg, logger=None): """ 取得したcookieを設定して、空き予約情報を取得する """ # 待機時間を設定する wait = WebDriverWait(driver, 10) # 検索ページがすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) #sleep(5) #for key, value in input_data_list.item(): # 検索日を指定して、空き予約を取得する for _date in date_list: #logger.debug(f'research: {key}: {value}') f_date = _date.replace('/', '') # 空き予約を検索する selenium_input_datas(driver, _date, logger=logger) # 検索結果をHTMLソースとしてオブジェクトに保存する _html = driver.page_source # デバッグ用にHTMLファイルを保存する #reserve_tools.save_result_html(_html, f'hachioji_empty_reserves_{f_date}.html') #sleep(1) # HTML解析を実行し、空き予約名リストを作成する get_empty_court_time(cfg, reserves_list, f_date, _html, logger=logger) # 条件をクリア ボタンをクリックして、次の検索の準備をする # 空き予約名リストを表示する #logger.debug(f'Court_Reserve_List:\n{reserves_list}') return reserves_list
def selenium_post_conditions(driver, date_list, reserves_list, cfg, logger=None): """ 空き予約情報を取得する """ # 待機時間を設定する wait = WebDriverWait(driver, 10, 2) # 検索ページがすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) # 検索日を指定して、空き予約を取得する for _date in date_list: #logger.debug(f'research: {key}: {value}') # 空き予約を検索する selenium_input_datas(driver, _date, logger=logger) # 検索結果をHTMLソースとしてオブジェクトに保存する _html = driver.page_source # デバッグ用にHTMLファイルを保存する #reserve_tools.save_result_html(_html, f'reserves_{_date}.html') #sleep(1) # HTML解析を実行し、空き予約名リストを作成する get_empty_court_time(cfg, reserves_list, _date, _html, logger=logger) # 「メニューへ」ボタンをクリックする go_to_search_reserves_page(driver, logger=logger) # 空き予約名リストを表示する #logger.debug(f'Court_Reserve_List:\n{reserves_list}') return reserves_list
def return_to_datesearch(driver, mouse, cfg, logger=None): """ 「空き状況の検索へ」リンクをクリックして「空き状況を検索」画面移動する """ global http_req_num # 待機時間を設定する wait = WebDriverWait(driver, 10) # 検索ページがすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) # メニューバーの「随時予約・抽選申込」をクリックする driver.find_element( By.XPATH, '//*[@id="pageTop"]/article/section/form/nav/a').click() http_req_num += 1 return driver, mouse
def selenium_input_datas(driver, input_date, logger=None): """ 検索条件を入力し、空き予約を検索し、検索結果を取得する """ global http_req_num # selectタイプの指定値 shisetsuId = 2 # テニスコート periodId = 1 # 指定日のみ # DOM上に表示されるまで待機する # 検索フォームのフィールド設定 wait = WebDriverWait(driver, 10) f_shisetsu = wait.until(EC.presence_of_element_located( (By.ID, "shisetsu"))) # 分類フィールドで施設を選択する Select(f_shisetsu).select_by_index(shisetsuId) # 開始日フィールドが表示されるまで待機後、指定する f_date = wait.until(EC.presence_of_element_located((By.NAME, "date"))) # 開始日フィールドに入力されている値をクリアする f_date.clear() # 開始日フィールドに指定日を入力する f_date.send_keys(str(input_date)) # 期間ラジオボタンで指定開始日のみを選択する # クリックできる状態まで待機する #wait.until(EC.element_to_be_clickable((By.NAME, "disp_type"))) #wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "btnSearch js_recaptcha_submit"))) # 期間ラジオボタンで「指定開始日のみ」を指定する f_period = driver.find_element( By.XPATH, "/html/body/div[1]/article/section[2]/div/form/table/tbody/tr[4]/td/table/tbody/tr[2]/td/div/label[1]" ) # 期間ラジオボタンで「指定開始日のみ」をクリックする f_period.click() # 画面を最下行までスクロールさせ、全ページを表示する driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 検索ボタンをクリックする driver.find_element( By.XPATH, ".//input[@type='button'][@value='検索する'][@class='btnSearch js_recaptcha_submit']" ).click() #sleep(30) # 検索結果がすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) sleep(1) # 最下行までスクロールする driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") http_req_num += 1 # 画面のtitleを確認する assert '空き状況を検索|八王子市施設予約システム' in driver.title #return cookie, ncforminfo_value return None
def selenium_go_to_search_menu(driver, mouse, cfg, cookies, logger=None): """ 空き状況を検索ページに移動する。 「空き状況を検索」ボタンをクリックする """ global http_req_num # 待機時間を設定する wait = WebDriverWait(driver, 10) # 検索ページがすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) # 空き状況を検索 画面に移動するため、右上の「空き状況を検索」ボタンをクリックする driver.find_element( By.XPATH, '/html/body/div[1]/header/section/div/form/p/a').click() http_req_num += 1 return None
def connect_to_approve(browser, request): base_url = request print("Jenkins Pull Request url:- "+base_url) try: browser.get(request.strip()) # wait for table element with id = 'hnmain' to load # before returning True wait = WebDriverWait(browser, 10) wait.until(visibility_of_element_located((By.XPATH, "//*[@class='aui-page-panel-inner']"))) return True except: print(f"WARNING: required elements not loaded to approve from {base_url}.") return False
def go_to_search_reserves_page(driver, logger=None): """ メニューボタンで空き予約検索ページに戻る """ global http_req_num # 待機時間を設定する wait = WebDriverWait(driver, 10, 2) # 検索ページがすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) # 「メニューへ」ボタンをクリックする f_MenuBtn = wait.until( EC.element_to_be_clickable((By.ID, "ucPCFooter_btnToMenu"))) f_MenuBtn.click() http_req_num += 1 # 空き予約検索ページに移動する wait.until(EC.presence_of_all_elements_located) return driver
def connect_to_base(browser, PullReqOpen): base_url = PullReqOpen print("Jenkins Pull Request url:- "+base_url) try: browser.get(PullReqOpen.strip()) # wait for table element with id = 'hnmain' to load # before returning True wait = WebDriverWait(browser, 5) wait.until(visibility_of_element_located((By.XPATH, "//*[@class='style-scope ytd-item-section-renderer']"))) return True except: print(f"WARNING: required elements not loaded to get open requests from {base_url}.") return False
def login_proc(cfg, headers, userid, password, logger=None): """ ログインする """ global http_req_num # 利用者番号とパスワードを設定する _userid = userid _password = password # クローラーの初期化 (driver, mouse) = setup_driver(headers) # 待機時間を設定する wait = WebDriverWait(driver, 10) # 空き予約ページにアクセスし、cookieを取得する (cookies, response) = selenium_get_cookie(driver, cfg, logger=logger) # 利用者番号とパスワードを入力する # 利用者番号フィールドが表示されるまで待機する f_userid = wait.until(EC.presence_of_element_located((By.NAME, "no"))) # 利用者番号フィールドに入力されている値をクリアする f_userid.clear() # 利用者番号フィールドに利用者番号を入力する f_userid.send_keys(str(_userid)) # パスワードフィールドが表示されるまで待機する f_password = wait.until( EC.presence_of_element_located((By.NAME, "password"))) # パスワードフィールドに入力されている値をクリアする f_password.clear() # パスワードフィールドにパスワードを入力する f_password.send_keys(str(_password)) # デバック用 # _html = driver.page_source # with open('top01.html', mode='w', encoding='utf-8', errors='ignore') as f: # f.write(_html) # 「ログイン」ボタンをクリックする driver.find_element( By.XPATH, '//*[@id="pageTop"]/article/section[2]/div/form[1]/table/tbody/tr[3]/td/input[4]' ).click() http_req_num += 1 # 「ご利用者さまトップ|八王子市施設予約システム」タイトルが含まれるまで待機する wait.until(EC.title_contains("ご利用者さまトップ|八王子市施設予約システム")) # 画面のtitleを確認する assert 'ご利用者さまトップ|八王子市施設予約システム' in driver.title return driver, mouse
def getCommitfilesList(reqURL,browser): try: browser.get(reqURL.strip()) wait = WebDriverWait(browser, 10) wait.until(visibility_of_element_located((By.XPATH, "//*[@class='changes-tree']"))) except: print(f"WARNING: required elements not loaded to get open requests from {reqURL}.") return False html=browser.page_source soup = BeautifulSoup(html,features="lxml") changeTree = soup.find("div",{"class":"changes-tree"}) rows = changeTree.findAll('a') for tr in rows: print("File:- "+str(tr.get('href'))) print("fileName:- "+str(tr.find('span',{"class":"file-label"})))
def go_to_datesearch(driver, mouse, cfg, logger=None): """ メニュー画面から「随時予約・抽選申込」を選択し、「空き状況を検索」画面移動する """ global http_req_num # 待機時間を設定する wait = WebDriverWait(driver, 10) # mypageのURLにリダイレクトされるまで待機する wait.until(EC.url_to_be(cfg['mypage_url'])) # 検索ページがすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) # デバック用 # _html = driver.page_source # with open('mypage.html', mode='w', encoding='utf-8', errors='ignore') as f: # f.write(_html) # メニューバーの「随時予約・抽選申込」をクリックする driver.find_element( By.XPATH, '/html/body/div[1]/article/section[2]/ul/li[1]/form/a').click() http_req_num += 1 # 検索ページがDOM上にすべて表示されるまで待機する #wait.until(EC.presence_of_all_elements_located) wait.until(EC.title_contains("空き状況を検索|八王子市施設予約システム")) # 画面のtitleを確認する assert '空き状況を検索|八王子市施設予約システム' in driver.title return driver, mouse
def entry_reserve(driver, mouse, logger=None): """ 空きコートを申し込む """ global http_req_num # 利用目的を「硬式テニス」とする # 硬式テニスの値 _purpose = 150 # 待機時間を設定する wait = WebDriverWait(driver, 10, 3) # 検索ページがすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) # 利用目的を選択する f_purpose = wait.until(EC.presence_of_element_located((By.ID, "purpose"))) f_purpose = wait.until(EC.element_to_be_clickable((By.ID, "purpose"))) f_purpose.click() #logger.debug(f'f_purpose: {f_purpose}') try: Select(f_purpose).select_by_value(f'{_purpose}') except exceptions.StaleElementReferenceException: f_facility = wait.until( EC.presence_of_element_located((By.ID, "purpose"))) Select(f_purpose).select_by_value(f'{_purpose}') except: pass # 利用目的を選択する #f_purpose = driver.find_element_by_xpath('//*[@id="purpose"]') # 利用目的フィールドに硬式テニスの値を選択する #f_purpose.select_by_value(f'{_purpose}') # 「申込」ボタンをクリックする f_entry = wait.until( EC.element_to_be_clickable(( By.XPATH, '//*[@id="pageTop"]/article/section/form[1]/table/tbody/tr[7]/td/input[4]' ))) # reCHAPTCHAでインターセプトされて、下記のアラームが発生することがあるため、click()をやめる # selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: #f_entry.click() driver.execute_script("arguments[0].click();", f_entry) http_req_num += 1 wait.until(EC.title_contains("随時予約(完了)|八王子市施設予約システム")) # 随時予約(完了)画面であることを確認する assert '随時予約(完了)|八王子市施設予約システム' in driver.title return driver, mouse
def selenium_get_cookie_and_html(driver, cfg, logger=None): """ selenuimuで接続して、スレッド毎にcookieを取得する """ global http_req_num wait = WebDriverWait(driver, 10, 2) # トップページにアクセスする。必要なくなったのでコメントアウトする。 # トップページでもcookieを発行している #response = driver.get(cfg['top_url']) #http_req_num += 1 # メニューページにアクセスする response = driver.get(cfg['first_url']) http_req_num += 1 # デバッグ用にHTMLファイルを保存する #reserve_tools.save_result_html(response.page_source, f'dselect.html') # 空き予約検索ページにアクセスする response = driver.get(cfg['second_url']) http_req_num += 1 # デバッグ用にHTMLファイルを保存する #reserve_tools.save_result_html(response.page_source, f'dselect.html') elment = wait.until(EC.presence_of_all_elements_located) return driver
def display_target_reserve(driver, mouse, date, facility_id, court_id, logger=None): """ 年月日、分類、施設名、ご利用目的、開始日、指定開始日のみを指定して、対象の空きコートを表示する """ global http_req_num # selectタイプの指定値 shisetsuId = 2 # テニスコート # 日付を「YYYYMMDD」から「YYYY/MM/DD」に変換する _date = date[:4] + '/' + date[4:6] + '/' + date[6:] #logger.debug(f'_date: {_date}') # DOM上に全て表示されるまで待機する wait = WebDriverWait(driver, 10, 3) # reserve/calenderのURLにリダイレクトされるまで待機する wait.until(EC.url_to_be(cfg['calender_url'])) # 検索ページがDOM上にすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) # デバック用 # _html = driver.page_source # with open('calender01.html', mode='w', encoding='utf-8', errors='ignore') as f: # f.write(_html) # 検索フォームのフィールド設定 f_shisetsu = wait.until(EC.presence_of_element_located((By.NAME, "class"))) # 分類フィールドで施設を選択する Select(f_shisetsu).select_by_value(f'{shisetsuId}') # DOM上で更新されるため、その更新期間だけ待機する time.sleep(1) # 施設名フィールドで、「施設名」を選択する f_facility = wait.until( EC.presence_of_element_located((By.NAME, "facility_id"))) f_facility = wait.until( EC.element_to_be_clickable((By.NAME, "facility_id"))) f_facility.click() #logger.debug(f'f_facility: {f_facility}') try: Select(f_facility).select_by_value(f'{facility_id}') except exceptions.StaleElementReferenceException: f_facility = wait.until( EC.presence_of_element_located((By.NAME, "facility_id"))) Select(f_facility).select_by_value(f'{facility_id}') except: pass #sleep(1) # 場所(面)フィールドで、「コート」を選択する # DOM上で更新されるため、その更新期間だけ待機する time.sleep(1) f_place = wait.until(EC.presence_of_element_located((By.ID, "place"))) #f_place = wait.until(EC.element_to_be_clickable((By.NAME, "place"))) f_place.click() #logger.debug(f'f_place: {f_place}') # デバック用 # _html = driver.page_source # with open('calender02.html', mode='w', encoding='utf-8', errors='ignore') as f: # f.write(_html) try: Select(f_place).select_by_value(f'{court_id}') except exceptions.StaleElementReferenceException: f_place = wait.until(EC.presence_of_element_located((By.ID, "place"))) Select(f_place).select_by_value(f'{court_id}') except: pass #sleep(1) # 開始日フィールドが表示されるまで待機後、指定する f_date = wait.until(EC.presence_of_element_located((By.NAME, "date"))) # 開始日フィールドに入力されている値をクリアする f_date.clear() # 開始日フィールドに指定日を入力する f_date.send_keys(str(_date)) # 期間ラジオボタンで「指定開始日のみ」を指定する f_period = driver.find_element( By.XPATH, '//*[@id="pageTop"]/article/section[2]/div/form/table/tbody/tr[4]/td/table/tbody/tr[2]/td/div/label[1]' ) # 期間ラジオボタンで「指定開始日のみ」をクリックする f_period.click() # 画面を最下行までスクロールさせ、全ページを表示する driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 検索ボタンをクリックする driver.find_element( By.XPATH, '//*[@id="pageTop"]/article/section[2]/div/form/table/tbody/tr[5]/td/input[2]' ).click() # 検索結果がすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) sleep(1) # 最下行までスクロールする driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") http_req_num += 1 # 画面のtitleを確認する assert '空き状況を検索|八王子市施設予約システム' in driver.title #return cookie, ncforminfo_value return driver, mouse
def selenium_input_datas(driver, input_date, logger=None): """ 検索条件を入力し、空き予約を検索し、検索結果を取得する """ # 待機時間を設定する wait = WebDriverWait(driver, 10, 2) global http_req_num # selectタイプの指定値 SSDaiClass = '01' # スポーツ施設 SSClass = '06' # テニスコート Term = '1日' Time = '全日' # 日付データを変換する _input_date = input_date[:4] + '/' + input_date[4:6] + '/' + input_date[6:] logger.debug(f'input_date: {_input_date}') # DOM上に表示されるまで待機する wait.until(EC.presence_of_all_elements_located) # 検索フォームのフィールド設定 # 施設の分類 f_SSDaiClass = wait.until( EC.presence_of_element_located( (By.ID, "wpManager_gwppnlLeftZone_cmbSSDaiClass"))) # セレクトフィールドの値がうまく取れないため、クリックできることを確認の上、try & except で対応する。他のも同様 f_SSDaiClass = wait.until( EC.element_to_be_clickable( (By.ID, "wpManager_gwppnlLeftZone_cmbSSDaiClass"))) f_SSDaiClass.click() try: Select(f_SSDaiClass).select_by_value(f'{SSDaiClass}') except exceptions.StaleElementReferenceException: f_SSDaiClass = wait.until( EC.presence_of_element_located((By.NAME, "SSDaiClass"))) Select(f_SSDaiClass).select_by_value(f'{SSDaiClass}') except: pass # 施設の種類 f_SSClass = wait.until( EC.presence_of_element_located( (By.ID, "wpManager_gwppnlLeftZone_cmbSSClass"))) f_SSClass = wait.until( EC.element_to_be_clickable( (By.ID, "wpManager_gwppnlLeftZone_cmbSSClass"))) f_SSClass.click() try: Select(f_SSClass).select_by_value(f'{SSClass}') except exceptions.StaleElementReferenceException: f_SSClass = wait.until( EC.presence_of_element_located((By.NAME, "SSClass"))) Select(f_SSClass).select_by_value(f'{SSClass}') except: pass # 開始日 f_Date = wait.until( EC.presence_of_element_located( (By.ID, "wpManager_gwppnlLeftZone_ucTermSettings_txtDateFrom"))) # 開始日フィールドに入力されている値をクリアする f_Date.clear() # 開始日フィールドに指定日を入力する f_Date.send_keys(str(_input_date)) # 期間 f_Term = wait.until( EC.presence_of_element_located( (By.ID, "wpManager_gwppnlLeftZone_ucTermSettings_cmbTerm"))) f_Term = wait.until( EC.element_to_be_clickable( (By.ID, "wpManager_gwppnlLeftZone_ucTermSettings_cmbTerm"))) f_Term.click() try: Select(f_Term).select_by_value(f'{Term}') except exceptions.StaleElementReferenceException: f_Term = wait.until( EC.presence_of_element_located( (By.NAME, "wpManager_gwppnlLeftZone_ucTermSettings_cmbTerm"))) Select(f_Term).select_by_value(f'{Term}') except: pass # 時間帯 f_Time = wait.until( EC.presence_of_element_located( (By.ID, "wpManager_gwppnlLeftZone_ucTermSettings_cmbTime"))) f_Time = wait.until( EC.element_to_be_clickable( (By.ID, "wpManager_gwppnlLeftZone_ucTermSettings_cmbTime"))) f_Time.click() try: Select(f_Time).select_by_value(f'{Time}') except exceptions.StaleElementReferenceException: f_Time = wait.until( EC.presence_of_element_located( (By.NAME, "wpManager_gwppnlLeftZone_ucTermSettings_cmbTime"))) Select(f_Time).select_by_value(f'{Time}') except: pass # 画面を最下行までスクロールさせ、全ページを表示する driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 「空き照会>>」ボタンをクリックする driver.find_element(By.ID, "wpManager_gwppnlLeftZone_btnShoukai").click() #sleep(30) # 検索結果がすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) #sleep(1) # 最下行までスクロールする driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") http_req_num += 1 return None
def get_current_reserves_list(driver, mouse, cfg, logger=None): """ 現在の予約情報を取得する - メニューバーの「予約確認/取り消し、抽選の確認/取消し、当選申請」をクリックして、予約一覧ページに移動する - 予約一覧を取得する - ページヘッダーメニューの「随時予約・抽選申込」をクリックして空き予約検索ページに移動する """ global http_req_num # 待機時間を設定する wait = WebDriverWait(driver, 10) # mypageのURLにリダイレクトされるまで待機する wait.until(EC.url_to_be(cfg['mypage_url'])) # 検索ページがすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) # デバック用 # _html = driver.page_source # with open('mypage.html', mode='w', encoding='utf-8', errors='ignore') as f: # f.write(_html) # メニューバーの「予約確認/取り消し、抽選の確認/取消し、当選申請」をクリックする #driver.find_element_by_xpath('/html/body/div[1]/article/section[2]/ul/li[2]/form/a').click() driver.find_element( By.XPATH, '/html/body/div[1]/article/section[2]/ul/li[2]/form/a').click() http_req_num += 1 # 予約一覧ページがDOM上にすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) wait.until(EC.title_contains("予約・抽選確認|八王子市施設予約システム")) # 画面のtitleを確認する assert '予約・抽選確認|八王子市施設予約システム' in driver.title _html = driver.page_source # デバック用 #with open('reserve.html', mode='w', encoding='utf-8', errors='ignore') as f: # f.write(_html) # 予約情報リストを取得する reserved_list = analyze_reserved_list(cfg, _html, logger=logger) # ページヘッダーメニューの「随時予約・抽選申込」をクリックする driver.find_element( By.XPATH, '//*[@id="pageTop"]/header/nav/ul/li[2]/form/a').click() http_req_num += 1 # 検索ページがDOM上にすべて表示されるまで待機する wait.until(EC.presence_of_all_elements_located) wait.until(EC.title_contains("空き状況を検索|八王子市施設予約システム")) # 画面のtitleを確認する assert '空き状況を検索|八王子市施設予約システム' in driver.title return driver, mouse, reserved_list