소프트웨어/Python

웹 드라이버 함수로 배치? 클래스로 배치?

Nerd Dog 2024. 5. 15.

 

최근에 웹 드라이버로 크롤링 툴을 만드는데

기존 방식은 셀레니움 웹드라이버를 선언 및 리턴하는 모습이었지만 뭔가 클래스에 넣어서 사용해보고 싶어서 바꿨는데

기존 방식이 가지는 메리트가 더 커서 다시 기존 방식으로 돌아갔다.

돌아간 이유

두 방식 모두 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

댓글

💲 추천 글