본문 바로가기
카테고리 없음

C# .NET 매크로 프로그램 만들기. (웹 업무 자동화 탐색 기능 구현)

by 업무자동화 2024. 6. 8.
반응형

유료 매크로 프로그램 다운로드

http://ngmsoftware.com/bbs/board.php?bo_table=product_review 

 

엔지엠소프트웨어

엔지엠 매크로는 복잡한 반복작업을 자동화할 수 있습니다. PC 게임, 모바일 게임을 최적으로 지원하며 모든 PC 프로그램 및 업무에 적용할 수 있습니다.

www.ngmsoftware.com

#매크로 #메크로 #매크로프로그램 #엔지엠소프트웨어 #엔지엠에디터 #엔지엠플레이어 #비활성매크로 #하드웨어매크로 #기계식매크로 #마우스광클릭 #키보드매크로 #이미지서치 #이미지매치 #블로그 #카페 #인스타그램 #유튜브 #소셜네트워크 #카카오톡 #텔레그램 #자동화

 

 

  • 엔지엠 커뮤니티 월 이용료: 4,500원, 1년 이용료: 55,000원 (전체 기능의 80프로)
  • 엔지엠 얼티밋 월 이용료: 6,500원, 1년 이용료: 77,000원 (전체 기능의 90프로)
  • 엔지엠 엔터프라이즈 월 이용료: 9,200원, 1년 이용료: 110,000원 (전체 기능 사용)

 

안녕하세요. 엔지엠소프트웨어입니다. 오늘은 웹 업무 자동화 RPA 프로그램을 이용해서 탐색 기능을 구현 해보겠습니다. 여기에서 탐색은 웹페이지에서 버튼, 링크, 텍스트 입력등등... 어떤 동작을 수행하는 엘리먼트(Element: 요소)를 찾는게 아닌 페이지와 관련된 내용입니다. 웹자동화를 만들려면 우선, 작업을 진행할 웹페이지에 접근해야 하잖아요? 그래서, 페이지에 접근하는 다양한 방법을 먼저 만들어야 합니다. 그리고, 엘리먼트에 접근해서 액션을 수행할 수 있도록 해줘야 합니다.

 

우선, 외부 API의 웹/인터넷에서 웹 제어라는 액션을 만들어야 합니다.

 

 

기본적으로 이 액션도 연결된 웹세션이 있어야 하기 때문에 연결된 브라우저의 이름을 선택해야 합니다. 그래서, WebBaseModel을 상속 받아서 기본적인 속성들은 자동으로 처리될 수 있도록 해주었습니다. 추가로, 필요한 인터페이스가 있으면 따로 구현해야 하는데요. 현재 상태에서는 딱히 필요한게 없어 보입니다.

public class NavigationModel : WebBaseModel

 

기본적인 정보들을 표시하기 위해 핸들 정보도 추가 해줍니다.

[LocalizedCategory("Data")]
[LocalizedDisplayName("CurrentWindowHandle")]
[LocalizedDescription("CurrentWindowHandle")]
[Browsable(true)]
[DefaultValue(null)]
[Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
public string? CurrentWindowHandle { get; set; }

[LocalizedCategory("Data")]
[LocalizedDisplayName("WindowHandles")]
[LocalizedDescription("WindowHandles")]
[Browsable(true)]
[DefaultValue(null)]
public string[]? WindowHandles { get; set; }

 

사용자가 선택하거나 입력해야 할 명령은 2개밖에 없습니다. 생각보다 내용이 간단한데요. 엔지엠 매크로 6에서는 하나의 액션에 너무 많은 기능을 넣어두어서 퍼포먼스도 떨어지고 코드량도 많아서 분석에 어려움이 많았습니다. 그래서, 이번에는 좀 더 타이트하게 행동을 분류해서 액션들을 나누는 방향으로 진행 했습니다. 하지만, 아직도 일부 액션들은 많은 옵션과 설정 값으로 인해 복잡도가 높은데요. 연관성이 이어지는 경우에는 어쩔 수 없을듯 합니다.

[LocalizedCategory("Action")]
[LocalizedDisplayName("WebAction")]
[LocalizedDescription("WebAction")]
[Browsable(true)]
[DefaultValue(typeof(Ai.Definition.NavigationOption), "GoToUrl")]
public Ai.Definition.NavigationOption WebAction { get; set; } = Definition.NavigationOption.GoToUrl;

[LocalizedCategory("Action")]
[LocalizedDisplayName("ActionParameter")]
[LocalizedDescription("ActionParameter")]
[Browsable(true)]
[DefaultValue(null)]
public string? ActionParameter { get; set; }

 

웹 액션의 종류에 따라서 처리를 분기 해줍니다.

switch (WebAction)
{
    case Definition.NavigationOption.GoToUrl:
        driver.Navigate().GoToUrl(ActionParameter);
        break;
    case Definition.NavigationOption.Forward:
        driver.Navigate().Forward();
        break;
    case Definition.NavigationOption.Back:
        driver.Navigate().Back();
        break;
    case Definition.NavigationOption.Refresh:
        driver.Navigate().Refresh();
        break;
    case Definition.NavigationOption.NewWindow:
        driver.SwitchTo().NewWindow(OpenQA.Selenium.WindowType.Window);
        break;
    case Definition.NavigationOption.NewTab:
        driver.SwitchTo().NewWindow(OpenQA.Selenium.WindowType.Tab);
        break;
    case Definition.NavigationOption.Close:
        driver.Close();
        break;
    case Definition.NavigationOption.CloseAll:
        foreach (var windowHandle in driver.WindowHandles)
        {
            driver.SwitchTo().Window(windowHandle);
            driver.Close();
        }
        break;
    case Definition.NavigationOption.SelectFirstWindow:
        driver.SwitchTo().Window(driver.WindowHandles.First());
        break;
    case Definition.NavigationOption.SelectLastWindow:
        driver.SwitchTo().Window(driver.WindowHandles.Last());
        break;
    case Definition.NavigationOption.SelectWindowName:
        string currentWindow = driver.CurrentWindowHandle;

        foreach (var windowHandle in driver.WindowHandles)
        {
            if (driver.SwitchTo().Window(windowHandle).Title == ActionParameter)
                currentWindow = windowHandle;
                break;
        }

        driver.SwitchTo().Window(currentWindow);
        break;
    case Definition.NavigationOption.SelectWindowNameByStartsWith:
        currentWindow = driver.CurrentWindowHandle;

        foreach (var windowHandle in driver.WindowHandles)
        {
            if (driver.SwitchTo().Window(windowHandle).Title.StartsWith(ActionParameter))
                currentWindow = windowHandle;
            break;
        }

        driver.SwitchTo().Window(currentWindow);
        break;
    case Definition.NavigationOption.SelectWindowNameByEndsWith:
        currentWindow = driver.CurrentWindowHandle;

        foreach (var windowHandle in driver.WindowHandles)
        {
            if (driver.SwitchTo().Window(windowHandle).Title.EndsWith(ActionParameter))
                currentWindow = windowHandle;
            break;
        }

        driver.SwitchTo().Window(currentWindow);
        break;
    case Definition.NavigationOption.SelectWindowNameByContains:
        currentWindow = driver.CurrentWindowHandle;

        foreach (var windowHandle in driver.WindowHandles)
        {
            if (driver.SwitchTo().Window(windowHandle).Title.Contains(ActionParameter))
                currentWindow = windowHandle;
            break;
        }

        driver.SwitchTo().Window(currentWindow);
        break;
    case Definition.NavigationOption.SelectWindowIndex:
        driver.SwitchTo().Window(driver.WindowHandles[int.Parse(ActionParameter)]);
        break;
    case Definition.NavigationOption.IFrameById:
        var iframes = driver.FindElements(OpenQA.Selenium.By.TagName("iframe"));
        
        foreach (var iframe in iframes)
        {
            if (iframe.GetAttribute("id") == ActionParameter)
            {
                driver.SwitchTo().Frame(iframe);
                break;
            }
        }
        break;
    case Definition.NavigationOption.IFrameByName:
        driver.SwitchTo().Frame(ActionParameter);
        break;
    case Definition.NavigationOption.IFrameByIndex:
        driver.SwitchTo().Frame(int.Parse(ActionParameter));
        break;
    case Definition.NavigationOption.ParentIFrame:
        driver.SwitchTo().ParentFrame();
        break;
    case Definition.NavigationOption.IFrameToMain:
        driver.SwitchTo().DefaultContent();
        break;
}

 

위의 코드가 그렇게 복잡하거나 어렵지는 않을겁니다. 코드를 유심히 보면, 동일한 코드가 반복되고 있는데요. 그 안에서 각각의 메소드만 다르게 적용시키고 있습니다. 그래서, 옵션에 따라서 접근할 위치와 접근하기 위한 값을 설정하는 것으로 대부분의 처리가 가능해집니다. 물론, 일부 예외도 있지만 이런 것들은 별도로 다루는걸로 해야 할듯 합니다. 아무래도 일관성을 해치는 기능을 여기에 포함시켜서 옵션과 설정 값을 추가하기 보다는 심플하게 가져가는게 좋겠다는 판단이거든요^^

 

아래 동영상은 다양한 방법으로 웹페이지를 탐색하는 방법을 설명하고 있습니다. 업무 자동화에 참고하시면 좋을듯 합니다.

https://youtu.be/WuKqWmfiZ1k

 

 

 

[ 각종 자동화 매크로 및 RPA 프로그램 제작 해드립니다. ]

[ 초보자도 쉽게 따라할 수 있는 기초 학습 강좌 보기 ]

 

원본 글 보기

http://ngmsoftware.com/bbs/board.php?bo_table=tip_and_tech 

 

엔지엠소프트웨어

엔지엠 매크로는 복잡한 반복작업을 자동화할 수 있습니다. PC 게임, 모바일 게임을 최적으로 지원하며 모든 PC 프로그램 및 업무에 적용할 수 있습니다.

www.ngmsoftware.com

 

반응형

댓글