파이썬 selenium execute_script는 JavaScript코드인 스크립트 형식으로 작동하게 됩니다.
그래서 사용할때 문자열로 작성하다 보니 자동 완성 안됨 과 코드가 길어지는 등 여러 단점이 있는데요
그걸 해결하고자 함수로 만들어 봤습니다.
소스코드
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.by import By
from string import Formatter
# 스크립트 전용 변수
script_Function =\
'''
function getElementByXpath(path) {
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}
'''
script_Content =\
'''
{function}
{console}
{OUTPUT}
'''
# .format형식 Default값 정의 클래스
class PartialFormatter(Formatter):
def __init__(self, missing='', bad_fmt='(포맷형식이 잘못됨!!)'):
self.missing, self.bad_fmt=missing, bad_fmt
def get_field(self, field_name, args, kwargs):
# Handle a key not found
try:
val=super(PartialFormatter, self).get_field(field_name, args, kwargs)
# Python 3, 'super().get_field(field_name, args, kwargs)' works
except (KeyError, AttributeError):
val=None,field_name
return val
def format_field(self, value, spec):
# handle an invalid format
if value==None: return self.missing
try:
return super(PartialFormatter, self).format_field(value, spec)
except ValueError:
if self.bad_fmt is not None: return self.bad_fmt
else: raise
def partialformat(basic_frame:str,inputDICT:dict):
return PartialFormatter().format(basic_frame,**inputDICT)
# execute_script 스크립트로 컨트롤
def execute_script(browser:WebDriver,pathName:str,Work=None,by:By=By.XPATH,use_Console=False):
r'''
browser:
webdriver.~~ return한 값 넣으면 됩니다.
pathName:
검사에서 복사한 PATH 값 또는 해당값 넣기
Work:
스크립트에서 사용하는 동작시킬수 있는 값 넣기 (사용법 Work = click)
by:
검사에서 복사한 PATH 값의 스타일
use_Console:
브라우저 콘솔에 출력할지
'''
# 최종 값들
total = {}
#### 형식 정의 ####
if by == By.XPATH:
global script_Function
total['function'] = script_Function
total['OUTPUT'] = "getElementByXpath('{pathName}'){choice}"
elif by == By.CSS_SELECTOR:
total['OUTPUT'] = "document.querySelector('{pathName}'){choice}"
elif by == By.ID:
total['OUTPUT'] = "document.getElementById('{pathName}'){choice}"
elif by == By.CLASS_NAME:
total['OUTPUT'] = "document.getElementsByClassName('{pathName}')[0]{choice}"
elif by == By.TAG_NAME:
total['OUTPUT'] = "document.getElementsByTagName('{pathName}')[0]{choice}"
###################
# 콘솔 출력
TEST = partialformat(total['OUTPUT'],{'pathName':pathName})
if use_Console:
total['console'] = 'console.log({});'.format(TEST)
# 작업 수행
if Work is not None:
final = {'pathName':pathName,'choice':'.{}();'.format(Work)}
total['OUTPUT'] = partialformat(total['OUTPUT'],final)
else:
total['OUTPUT'] = '{};'.format(TEST)
# 최종 출력 형식
global script_Content
final=partialformat(script_Content,total)
# print(final)
browser.execute_script(final)