import json
import logging
import time
import pathlib
import sys
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager
import PySimpleGUI as sg
import logging
formatter = '[%(asctime)s] %(levelname)s: %(message)s'
logging.basicConfig(
level=logging.INFO,
format=formatter,
)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# ファイルへ出力
file_handler = logging.FileHandler('jpea_appli.log', encoding='utf-8')
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(logging.Formatter(formatter))
logger.addHandler(file_handler)
BASE_URL = 'https://www.fit-portal.go.jp/mypage/UserLogin'
PLANT_ID_FILE = "C:\Users\●●●\Desktop\JPEA_APPLICATION\plant_id_etc.xlsx"
JSON_FILE = './jpea_app.json'
class LoginIdPw:
def __init__(self, id, pw):
self.id = id
self.pw = pw
user_1 = LoginIdPw('', '')
user_2 = LoginIdPw('', '')
user_3 = LoginIdPw('', '')
# SB公開情報から(ふりがな:~、氏名:~の箇所は削除)
officers =
{'1': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'2': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'3': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'4': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'5': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'6': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'7': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'8': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'9': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'10': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'11': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'12': {'役職': '取締役', 'ふりがな': '...', '氏名': '...'},
'13': {'役職': '監査役', 'ふりがな': '...', '氏名': '...'},
'14': {'役職': '監査役', 'ふりがな': '...', '氏名': '...'},
'15': {'役職': '監査役', 'ふりがな': '...', '氏名': '...'},
'16': {'役職': '監査役', 'ふりがな': '...', '氏名': '...'}}
logger.info('▼プログラム開始')
logger.info('webdirverを読み込み')
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()),)
driver.implicitly_wait(10)
driver.minimize_window()
driver.maximize_window()
logger.info('ログインページを開く')
driver.get(BASE_URL)
# 役員情報を取得する
def get_officer_info(No: int):
No = str(No)
post = officers[No]["役職"]
kana = officers[No]["ふりがな"]
name = officers[No]["氏名"]
return (No, post, kana, name)
# 入力済みの役員情報のROW数をカウント
def get_executive_rownums():
executive_info_rows = driver.find_elements(By.CSS_SELECTOR, 'table[class="form_table accEs"] td[class="td_input"][colspan="2"]')
rownums = len(executive_info_rows)
return rownums
# 役員情報の入力
def input_executive_info(No: int):
executive_post_area = driver.find_element(By.NAME, f'page:form:j_id666:{No-1}:j_id677')
executive_kana_area = driver.find_element(By.NAME, f'page:form:j_id666:{No-1}:j_id687')
executive_name_area = driver.find_element(By.NAME, f'page:form:j_id666:{No-1}:j_id697')
executive_post_area.clear()
executive_kana_area.clear()
executive_name_area.clear()
_, post, kana, name = get_officer_info(No)
executive_post_area.send_keys(post)
executive_kana_area.send_keys(kana)
executive_name_area.send_keys(name)
# 新規追加のため、役員情報のROWを追加
def append_executive_row(No: int):
try:
print(f'No:{No} の行を追加中')
driver.find_element(By.ID, f'page:form:j_id666:{No-2}:addt').click()
except Exception as e:
print(f'処理を中断します。\n{e}')
sys.exit()
# 役員16名のデータを追加
def input_info_16_executive():
No = 1
while No <= rownums:
print(f'No:{No} {officers[str(No)]["氏名"]} を入力中')
try:
input_executive_info(No)
# time.sleep(1)
No += 1
except Exception as e:
print(f'処理を中断します。\n{e}')
sys.exit()
while No <= 16:
append_executive_row(No)
# time.sleep(3)
try:
print(f'No{No}:{officers[str(No)]["氏名"]} を入力中')
input_executive_info(No)
# time.sleep(1)
No += 1
except Exception as e:
print(f'処理を中断します。\n{e}')
sys.exit()
# チェックボックスON用(checkboxがTrue:何もしない、False:ON)
def check_box_according_cond(elem):
if elem.is_selected():
print("checkbox status: Remains 'ON' ")
pass
else:
elem.click()
print("checkbox status: OFF > ON")
# TODO 切り替えるときはログアウトが必要
user_id, user_pw = user_2.id, user_2.pw
logger.info('ID/PWでログイン開始')
id = driver.find_element(By.ID, 'loginPage\:j_id3\:username')
id.send_keys(user_id)
pw = driver.find_element(By.ID, 'loginPage\:j_id3\:password')
pw.send_keys(user_pw)
login_btn = driver.find_element(By.NAME, 'loginPage:j_id3:j_id33')
login_btn.click()
logger.info('ID/PW画面から遷移開始')
# logger.info("マイページ > 認定設備")
# topmenu_mod_plant = driver.find_element(By.CSS_SELECTOR, 'li[class="mode_plant"]')
# topmenu_mod_plant.click()
# logger.info("マイページ > 認定設備")
# leftmenu_plant_list =
logger.info("認定設備一覧へ遷移開始")
URL_PLANTLIST = 'https://www.fit-portal.go.jp/mypage/PlantList'
driver.get(URL_PLANTLIST)
setsubi_id = ''
logger.info(f"認定IDを取得:{setsubi_id}")
logger.info(f"{'-'*20}▼ {setsubi_id} {'-'*20}")
logger.info("認定IDを入力開始")
input_setsubi_id = driver.find_element(By.ID, 'page:form:j_id85')
input_setsubi_id.clear()
input_setsubi_id.send_keys(setsubi_id)
logger.info("検索を開始")
search_btn = driver.find_element(By.ID, 'page:form:comBtn')
search_btn.click()
logger.info("結果を参照")
btn_sansyo = driver.find_element(By.CSS_SELECTOR, 'input[value="参照"]')
btn_sansyo.click()
logger.info("変更認定申請ボタンをクリック")
btn_appli_for_change = driver.find_element(By.CSS_SELECTOR, 'input[alt="変更認定申請"]')
btn_appli_for_change.click()
logger.info("---変更申請登録画面---")
logger.info("「変更認定申請」をON")
driver.find_element(By.CSS_SELECTOR, 'input[value="変更認定申請"]').click()
logger.info("「変更内容」> 「事業者の選択(0)」と「その他(5)をON")
change_contents_checkboxes = driver.find_elements(By.CSS_SELECTOR, 'input[name="page:form:changeContentsCheckboxes"]')
change_contents_checkboxes[0].click()
change_contents_checkboxes[5].click()
change_reason_text_area = driver.find_element(By.ID, "page:form:changeReasonText")
change_reason_text_area.clear()
change_reason_text_area.send_keys("必須項目に入力したため")
logger.info("「新たに事業者を登録します」をON")
change_installer_checkbox = driver.find_element(By.ID, 'page:form:changeInstaller')
change_installer_checkbox.click()
time.sleep(5)
logger.info("「事業者名(ふりがな)を入力」")
corp_name_kana = driver.find_element(By.CSS_SELECTOR, 'input[name="page:form:j_id202"]')
corp_name_kana.clear()
corp_name_kana.send_keys("そふとばんくかぶしきかいしゃ")
logger.info("「事業者名」を入力")
corp_name_kanji = driver.find_element(By.CSS_SELECTOR, 'input[name="page:form:accName"]')
corp_name_kanji.clear()
corp_name_kanji.send_keys("ソフトバンク株式会社")
logger.info("「法人番号」を入力")
corp_num = driver.find_element(By.ID, 'page:form:accNoHoujinCd')
corp_num.clear()
corp_num.send_keys('9010401052465')
logger.info("「法人の代表者氏名」>「役職、ふりがな、氏名」を入力")
corp_represent_post = driver.find_element(By.ID, "page:form:accRepresentPos")
corp_represent_name_kana = driver.find_element(By.NAME, "page:form:j_id330")
corp_represent_name = driver.find_element(By.ID, "page:form:accNmCoPresident")
corp_represent_post.clear()
corp_represent_post.send_keys('代表取締役')
corp_represent_name_kana.clear()
corp_represent_name_kana.send_keys('みやかわ じゅんいち')
corp_represent_name.clear()
corp_represent_name.send_keys('宮川 潤一')
logger.info("事業者の住所")
logger.info("事業者の住所 > 郵便番号を入力開始")
post1 = driver.find_element(By.ID, "page:form:pos1")
post2 = driver.find_element(By.ID, "page:form:pos2")
post1.clear()
post1.send_keys('105')
post2.clear()
post2.send_keys('7529')
post_btn = driver.find_element(By.CSS_SELECTOR, 'input[name="page:form:j_id370"]')
post_btn.click()
time.sleep(5)
logger.info("事業者の住所 > 郵便番号を選択")
driver.find_element(By.CSS_SELECTOR, 'input[type="submit"][class="input_btn"][value="選択"]').click()
time.sleep(3)
logger.info("事業者の住所 > ふりなが入力")
addr_kana = driver.find_element(By.NAME, "page:form:j_id393")
addr_kana.clear()
addr_kana.send_keys('とうきょうとみなとくかいがん')
logger.info("事業者の住所 > 町名・番地を入力")
town_name_block_num = driver.find_element(By.NAME, "page:form:j_id418")
town_name_block_num.clear()
town_name_block_num.send_keys('海岸1-7-1')
logger.info("法人 > 代表TEL")
corp_tel_no = driver.find_element(By.NAME, "page:form:j_id440")
corp_tel_no.clear()
corp_tel_no.send_keys('093-288-0111')
logger.info("法人 > メアド")
corp_mail = driver.find_element(By.NAME, "page:form:j_id465")
corp_mail.clear()
corp_mail.send_keys('sbmgrp-epower@g.softbank.co.jp')
logger.info("法人 > メアド確認用")
corp_mail_for_confirm = driver.find_element(By.NAME, "page:form:j_id483")
corp_mail_for_confirm.clear()
corp_mail_for_confirm.send_keys('sbmgrp-epower@g.softbank.co.jp')
logger.info("担当者 > 氏名")
staff_last_name_kana = driver.find_element(By.NAME, 'page:form:j_id509')
staff_first_name_kana = driver.find_element(By.NAME, 'page:form:j_id517')
staff_last_name = driver.find_element(By.NAME, 'page:form:j_id525')
staff_first_name = driver.find_element(By.NAME, 'page:form:j_id533')
staff_last_name_kana.clear()
staff_last_name_kana.send_keys('')
staff_first_name_kana.clear()
staff_first_name_kana.send_keys('')
staff_last_name.clear()
staff_last_name.send_keys('')
staff_first_name.clear()
staff_first_name.send_keys('')
logger.info("担当者 > 連絡先番号")
staff_tel_no = driver.find_element(By.ID, "page:form:conPhone")
staff_tel_no.clear()
staff_tel_no.send_keys('093-288-0111')
logger.info("担当者 > 連絡先メアド")
staff_mail = driver.find_element(By.ID, "page:form:j_id593")
staff_mail.clear()
staff_mail.send_keys('sbgrp-solar_yahata@e.softbank.co.jp')
logger.info("担当者 > 連絡先メアド(確認用)")
staff_mail_for_confirm = driver.find_element(By.NAME, "page:form:j_id611")
staff_mail_for_confirm.clear()
staff_mail_for_confirm.send_keys('sbgrp-solar_yahata@e.softbank.co.jp')
logger.info("事業者名 > 変更理由")
reason_change_installer = driver.find_element(By.ID, "page:form:j_id620")
reason_change_installer.clear()
reason_change_installer.send_keys('事業譲渡')
logger.info("法人の役員情報【変更後】")
rownums = get_executive_rownums()
logger.info(f'すでに入力済みの役員情報数:{rownums}')
logger.info("役員16名を追加開始")
input_info_16_executive()
logger.info("太陽光発電設備の設置形態 > 「屋根設定」をON")
install_on_loof = driver.find_element(By.ID, "page:form:papRoofLoc")
check_box_according_cond(install_on_loof)
time.sleep(3)
logger.info("太陽光発電設備の設置形態 > 「既設の建物」をON")
existing_buildings = driver.find_element(By.ID, "page:form:roofBldRadio:0")
existing_buildings.click()
time.sleep(3)
logger.info("太陽光発電設備の設置形態 > 「事業者以外が所有」をON")
owner_buildings = driver.find_element(By.ID, "page:form:roofSecStatusRadio:1")
owner_buildings.click()
logger.info("太陽光発電設備の設置形態 > 「建物の種類」 > いったん「一戸建ての住宅」をON")
# TODO 謄本の①種類と突合させる必要あり。
# Apartment_house = "共同住宅"
# Offices_factories_stores = "事務所・工場・店舗"
# Schools_public_facilities = "学校・公共施設"
# Others = "その他"
building_type = driver.find_element(By.NAME, "page:form:roofBldSelect")
Single_family_dwellings = "一戸建ての住宅"
Select(building_type).select_by_value(Single_family_dwellings)
time.sleep(3)
logger.info("太陽電池の合計出力(kW) > 「合計出力を確認しました」をON")
confirmed_total_output = driver.find_element(By.ID, "page:form:checkedPanelOutput")
check_box_according_cond(confirmed_total_output)
logger.info("配線方法 > 「Z:全量配線」をON")
wiring_method = driver.find_element(By.ID, "page:form:j_id1631:0")
wiring_method.click()
logger.info("電気事業者への電気供給量の計測方法 >「単独計測」をON")
measure_method = driver.find_element(By.NAME, "page:form:j_id1778")
Select(measure_method).select_by_value("単独計測")
time.sleep(3)
logger.info("保守点検責任者")
logger.info("保守点検責任者 > 「事業者情報を反映」")
reflect_business_info_btn = driver.find_element(By.ID, "page:form:j_id1934")
reflect_business_info_btn.click()
time.sleep(5)
logger.info("保守点検責任者 > 「責任者氏名」")
mainte_manager_name = driver.find_element(By.ID, "page:form:nmMainteManager")
mainte_manager_name.clear()
mainte_manager_name.send_keys('')
logger.info("保守点検責任者 > 「所属・役職」")
mainte_manager_post = driver.find_element(By.ID, "page:form:mainteDeptOrPos")
mainte_manager_post.clear()
mainte_manager_post.send_keys('サービス推進部')
logger.info("遵守事項のチェック9個をON")
compliance_checkboxs = driver.find_elements(By.CSS_SELECTOR, 'div[id="page:form:businessCheckList"] input[type="checkbox"]')
for n, checkbox in enumerate(compliance_checkboxs, 1):
time.sleep(0.5)
print(f'{n}:', end="")
check_box_according_cond(checkbox)
logger.info("確認事項のチェック6個をON")
confirmation_checkboxs = driver.find_elements(By.CSS_SELECTOR, 'div[id="page:form:acceptanceCheckList"] input[type="checkbox"]')
for n, checkbox in enumerate(confirmation_checkboxs, 1):
time.sleep(0.5)
print(f'{n}:', end="")
check_box_according_cond(checkbox)
logger.info(f"{'-'*20}▲ {setsubi_id} {'-'*20}")
time.sleep(300)
driver.quit()
'''
TODO <エラー処理をどうするか>
1)
ログイン1
ログイン2
ログイン3
入力(保存なし)
入力(保存あり)- 添付(保存なし)
入力(保存あり)- 添付(保存あり) - 申請まだ
入力(保存あり)- 添付(保存あり) - 申請済み
2)
try:
~~~~
else:
except Exception as e:
finally:
driver.quit()
3)
df.loc[df['A'] == '1', 'C'][0] -> 5
d_dict = df.to_dict()
d_dict['col1']['row1'] = 'abc'
'''