최근에 웹 드라이버로 크롤링 툴을 만드는데
기존 방식은 셀레니움 웹드라이버를 선언 및 리턴하는 모습이었지만 뭔가 클래스에 넣어서 사용해보고 싶어서 바꿨는데
기존 방식이 가지는 메리트가 더 커서 다시 기존 방식으로 돌아갔다.
돌아간 이유
두 방식 모두 find 내부에 find_element를 사용해 내부 인자를 찾는다.
작동 방식은 이 글을 참조하면 될 것이다.
아무튼 find로 내부 인자를 찾는데 인자가 겹치는 경우도 많고 러시아 마트로시카처럼 인자 안에 인자를 찾아야 하는 경우도 많이 생기다 보니 다음과 같이 해당 함수를 두 번 사용해서 작동하는 것을 기대했다.
self.find(첫번째 인자).find(두번째 인자)
하지만 할 수 없다. 왜냐하면 첫 self.find(첫번째 인자)의 반환 값은 WebElement이기 때문이다.
def find_element(self, by=By.ID, value: Optional[str] = None) -> WebElement:
그래서 WebElement에는 find 함수가 없어서 만약 제대로된 인자를 찾고 싶다면 이렇게 구동시켜야 하고
find 함수를 만든 의미가 퇴색된다.
self.find(첫번째 인자).find_element(CSS_SELECTOR, 두 번째 인자와 + 복잡한 설정들)
그렇다면 이렇게 함수를 만드는게 효율적일 것이다.
elem = find(웹드라이버 혹은 웹엘레멘트, 첫 번째 인자)
elem2 = find(elem , 두번째 인자)
또한 매번 바깥에서 driver = Webdriver() 이런 식으로 클래스를 생성했다면
해당 클래스 내부 web을 find 함수에 넣어줘야지 작동하기에 여러가지 불편함이 생긴다.
결국 클래스를 사용하는 방식이 비효율적이라 다시 기존방식으로 롤백하게 된 것이다.
기존 방식
def openWebDriver(url :str):
driver.get(url)
return driver
def find(element,*classes, nth = None, add = None ,value = None, get_value = None):
try:
selector = ' '.join(f'.{cls}' for cls in classes)
elements = element.find_elements(By.CSS_SELECTOR, selector)
if nth is not None:
if nth - 1 < len(elements):
element = elements[nth - 1]
else:
raise IndexError(f"No element found at index {nth}")
else:
element = elements[0]
if add:
element = element.find_element(By.CSS_SELECTOR, f".{add}")
if value :
element.send_keys(value)
return True
if get_value:
return element.get_attribute("value")
return element
except Exception as e:
print(f"An error occurred: {e}")
return None
바뀐 방식
class Webdriver:
def __init__(self,url):
self.web = webdriver.get(url)
def __del__(self):
self.web.quit()
def find(self,*classes, nth = None, add = None ,value = None, get_value = None):
try:
selector = ' '.join(f'.{cls}' for cls in classes)
elements = self.web.find_elements(By.CSS_SELECTOR, selector)
if nth is not None:
if nth - 1 < len(elements):
element = elements[nth - 1]
else:
raise IndexError(f"No element found at index {nth}")
else:
element = elements[0]
if add:
element = element.find_element(By.CSS_SELECTOR, f".{add}")
if value :
element.send_keys(value)
return True
if get_value:
return element.get_attribute("value")
return element
except Exception as e:
print(f"An error occurred: {e}")
return None
결론
뭐 아무튼 만사 클래스에 넣는다고 좋은 코드는 아니라는 점을 깨달았음...
'소프트웨어 > Python' 카테고리의 다른 글
find_element 함수 개조 (0) | 2024.05.15 |
---|---|
PYQT5 스타일시트 적용 (0) | 2024.05.14 |
크롬드라이버 최신버전 다운링크 (0) | 2024.04.10 |
PYQT5 Drag & Drop 기능 (0) | 2024.02.25 |
PYQT5 아이콘 넣기 (0) | 2024.02.25 |
댓글