드물게 Find Children을 통해 element값을 가져와서 동적으로 처리해야 하는 케이스가 발생한다.

그 과정에서 기준 요소를 찾고 규칙적인 값을 Datascraping으로 가져올 수 있다.

다만 규칙에 반하는 예외요소들이 있을 수 있다.

가령 호텔의 후기를 가져오는데 어떤 후기는 특정 값이 채워져 있고 어떤 후기는 안 채워져 있어서

후기 폼이 달라진다고 가정하자.

이 경우 2가지 접근법이 있을 수 있다.

1. Datascraping을 경우의 수만큼 n번 나눠서 하고 결과물을 merge한다.

2. 각 element를 쪼개면서 조건을 따지고 가져온다.

2번으로 하고 싶은 경우 먼저 Find Children으로 element ienumerable을 가져오고,

각각의 element의 속성값을 가져와야 한다.

단, 이 방식은 VB.NET으로만 되는 것으로 보인다. (C# 템플릿에서는 해당 method가 없음)

[VB.NET] 에서의 방식

assign을 활용해 다음과 같이 설정

sValue = DirectCast(uiElementVar.Get("text"), String)

[Get의 ToString이 어떤 형태를 overide해야 할지를 모르기 때문에 에러가 난다. 예를 들어 속성값중 boolean인 value도 있고 region 객체가 나올 수도 있다. 그래서 DirectCast를 했는데 스타일에 따라 object로 일단 받아놓고 그 값을 ToString해서 쓸 수도 있다.]

[C#]에서의 방식

invoke code를 통해 다음과 같이 설정

Arguments에 in으로 uielement 변수, out으로 value를 받을 string 변수 설정

string elementText = uielementVar.Get("innertext").ToString();
sResult = elementText;

 

이때 get을 해오는 기전은 DataScraping이 하는 것과 동일하다.

(Find Children을 할 때 이미 한번에 해당 데이터 아래의 요소들을 한번에 다 긁어온 거로 볼 수 있다.)

따라서 각각 get Text를 하는 것에 비해 속도가 월등히 빨라진다.

복잡한 조건으로 가져오는 게 아니라면 웬만하면 Datascraping으로 가져오는 것을 권장한다.

https://jnaul.tistory.com/333

 

[Uipath] Data Scraping에 대해[2023-03-02 수정]

1. DataScraping이란? Uipath의 강력한 장점 중 하나는 RPA의 Main Demand에서 많은 비중을 차지하는 '웹크롤링'을 코딩하는 생산성이 매우 좋다는 점이다. 그걸 가능하게 해주는 핵심적인 기능이 Data Scrapin

jnaul.tistory.com

 

※ aaname같이 uipath에서 임의로 붙여주는 것은 못 가져오는 케이스도 있어 보인다. 별 문제가 없으려면 최대한 element 내부의 고유 속성 기준으로 가져와야 될 거 같다.

※ 기왕 나눠서 가져오고 있다면 값에 대한 정합성 체크를 넣어주는 것을 추천드린다. 그러지 않고는 이런 구조로 가져갔을 때의 장점이 많이 사라진다.

유지보수 cost때문에 Linq를 아주 권장하지는 않지만,

row의 type으로 인한 이슈나 속도 이슈를 막기 위해서,

꼭 써야될 때가 있다.

특히 datatable간의 비교가 많은데 다음과 같은 경우 2개가 질문이 많이 나오는 걸로 보인다.

 

[상황1] dtData1의 키값이 dtData2의 키컬럼에 존재하는 경우 포함[키컬럼 type은 int]

[Assign] dtOutput = (from row1 in dtData1.AsEnumerable()
                     join row2 in dtData2.AsEnumerable() on row1.Field<int>("Key") equals row2.Field<int>("Key")
                     select row1).CopyToDataTable()

 

[상황2] dtData1의 키값이 dtData2의 키컬럼에 존재하는 경우 미포함[키컬럼 type은 int]

[Assign] TempKeys = (dtData2.AsEnumerable().Select(row => row.Field<int>("Key"))).ToArray()

[Assign] dtOutput = (dtData1.AsEnumerable().Where(row => !tempjoin.Contains(row.Field<int>("Key")))).CopyToDataTable()

스튜디오 레벨 디버깅의 활용

uipath studio에서는 디버깅 모드 실행을 제공한다.

디버깅 모드는 지정된 포인트 혹은 에러에 도달했을 때, 멈춰서 변수들이나 현재 프로세스의 상태를 보여주는 모드이다.

활용 방식

1. Breakpoint

2. Locals

3. Watch

4. Immediate

 

1. Breakpoint [단축키 F9]

- breakpoint는 잠깐 멈추는 지점을 의미한다. [다른 언어들도 공통되는 개념]

- breakpoint로 지정된 line(또는 activity)은 실행되지 않고 그 직전까지 실행된다.

- breakpoint로 지정하면 빨간색 표시가 뜬다.

- breakpoint로 멈추는 것에 조건을 줄 수도 있다. 그렇게 설정하면 해당 포인트에서 특정 조건이 달성되면 멈춘다.

Conditional Breakpoint

- 해당 지점에서 멈췄을 경우 Log도 따로 지정 가능하다. 이런 기능을 사용하면 로깅을 위해 굳이 if문을 만들어줄 필요가 없다. 특히 output datatable 같은 거 해서 로그 찍어놓고 확인하는 그런 경우가 많은데 굳이 그럴 필요가 없다. [이 setting도 있지만 아래에서 소개하는 기능을 활용하는 게 훨씬 편하다.]

- 스위치는 bulk로 끄고 켤 수도 있다. 

위쪽 버튼을 활용하면 한꺼번에 껐다가 한꺼번에 켰다가 할 수도 있다.

2. Locals

- Locals에는 현재 break된 곳에 있는 모든 변수의 상태값을 보여준다.

- breakpoint와 함께 활용되어 실제 값이 어떻게 들어가는지 간단하게 볼 수 있다.

- 연필모양을 누르면 값을 볼 수 있고, 값을 편집하고 그 상태로 이어서 수행하는 것도 가능하다.

Locals의 예시. break된 scope에서 call할 수 있는 변수가 모두 나온다.

3. Watch

- 변수들의 특정값을 지정해서 추적할 수 있다.

- 가령 Locals에서는 dtContainer의 값을 보여주지만, dtContainer.AsEnumerable.Skip(i_irownum).Take(i_itakenum).CopyToDataTable 같은 값은 보여주지 않는다. 하지만 그런 값을 디버깅할 때 추적해야 한다면 여기에 기입하고 추적하면 된다.

 

4. Immediate

- 값을 쓰면 즉각적으로 표시된다. 다른 언어로 치면 terminal이나 console창 느낌으로 보면 된다.

- 예를 들어, dtContainer를 쓰면 dtContainer의 내용이 표시된다.

- 추적할 값으로 설정할 필요는 없으나 즉각적으로 어떤 변수의 값을 확인하고 싶은 경우 활용할 수 있다.

- dayofweek같은 걸 추적으로 찍어놨는데 dayofweek의 .ToString('d')값과 .Tostring('g')값이 어떤 차이가 있는지 같은 걸 확인할 때 많이 쓴다.

- 드물게 특정값을 편집하는 용도로 쓸 수도 있다.

'RPA Uipath > Uipath 디버깅' 카테고리의 다른 글

[Uipath] AR 봇 연결 끊김 이슈  (0) 2024.07.31
Uipath의 디버깅 시리즈1  (0) 2023.06.10

0. 디버깅에 관해

1. console 또는 log 찾기

2. 윈도우 환경

3. 브라우저

4. 네트워크

--------------------------------------------------------------------------------------------------------------------------------------------------------

0. 디버깅에 관해

개발자 업무의 절반 이상은 디버깅이다.

그럴 수밖에 없는 것이 어떤 service를 만드는 기간이든

그걸 운영하는 기간이든 간에 에러와 시행착오는 항상 존재하기 때문이다.

따라서 얼마나 적확하게 디버깅을 하느냐가 개발과 운영을 잘하느냐를 결정한다.[각주:1]

 

우리는 모든 에러를 겪어볼 수 없다.

새로운 에러는 언제든 등장하고 원인을 분석하고 해결하는 일은 개발자의 몫이다.

이 시리즈에서는 RPA, Uipath를 개발하는 입장에서 디버깅을 어떻게 할 수 있을까에 대해 정리를 해보려고 한다.

먼저 이번 글에서는 디버깅을 하기 위한 근거를 어떻게 찾아야 되는지를 다루려고 한다.

 

1. console 또는 log 찾기

  제대로 된 프로그램이라면 에러가 나든 안 나든 진행상황에 관해 어디든 찍어놨을 가능성이 높다.

보통 그것들은 console이라 불리는 곳에 찍히거나 log가 쌓이는 곳에 적재된다.

에러가 발생했다면 기본적으로는 다루는 툴의 console이나 log 위치를 찾아보고 파악해야 한다.

그 위치는 로컬일 수도 있고, 오케스트레이터 서버일 수도 있고 또는 타겟 프로그램일 수도 있다.

Uipath 기준에서는 가장 기본이 되는 로컬 로그나 오케 로그를 우선적으로 체크해야 한다.

 

2. 윈도우 환경

  RPA 환경은 윈도우 환경이다. 이렇게 단정적으로 말하는 이유는 linux나 mac은 일반적으로 전문가 영역이기 때문이다.

유저도 적을 뿐더러 그런 영역에서는 굳이 RPA를 써가며 자동화할 일이 거의 없다.

다행히도 윈도우에서는 이벤트 뷰어라는 강력한(?) 로깅툴이 존재한다.

이벤트 뷰어

윈도우에서 일어나는 대부분의 행위는 여기에 로그가 찍힌다.

어떤 계정으로 몇시 몇분에 로그인이 됐고 무슨 프로그램을 설치 또는 설치 실패했으며,

어떤 서비스가 돌다가 인증을 실패했고 뭐 그런 로그들이다.

보통 응용 프로그램에 우리가 찾는 로그들이 많이 찍혀있다.

여기까지 찾아온다는 것은 'uipath 로그에서는 원인이 애매하게 찍혀있는데 화면으로 봐도 특별한 뭐가 없고 에러는 왜인지 모르겠는데 자꾸 발생한다'는 경우다.

 

3. 브라우저

  RPA 과제들은 브라우저로 접속해서 데이터를 추출하는 경우가 많다.

브라우저는 html을 해석하고 api를 호출해주는 툴이기 때문에 자체적인 console이 아주 잘 발달돼 있다.

F12를 누르면 개발자 도구가 뜬다.

글을 작성하는 와중에 자동저장이 호출되는 것을 볼 수 있다.

여기서 콘솔탭을 누르면 웹페이지가 로드되면서 나오는 로깅을 볼 수 있다

굉장히 깔끔한 콘솔

웹에서 특정 버튼을 눌렀는데 평소엔 잘 되다가 반응이 갑자기 안 된다? 그럼 여기서 이유가 다 찍힌다.

나오는 문구로 구글링을 해보자.

Elements 탭에서는 다음과 같이 Css selector를 copy할 수 있는데

구조 변경 등으로 인해 셀렉터가 안 잡히거나, 데이터 스크래핑이 안 되는 경우

이 기능으로 비교해보면서 빠르게 디버깅이 가능하다.

이 정도면 크롬이 무거워도 용서해주자....

ctrl + f로 검색하거나 모바일 크기로 줄이기 같은 기능들도 아주 유용하다.

 

4. 네트워크

네트워크 영역은 대부분 최초 환경 세팅에서 디버깅하게 된다.

결국은 방화벽 문제일 가능성이 높고, 회사 내부 정책에 따라 조치해야 한다.

RPA 개발자 입장에서 문제는 보안 담당자가 '뚫어는 줄텐데 뭐 뚫어줘야 되는지는 너가 알아서 가져와'라고 했을 때이다.

그럼 Trigger후 Traffic 변화를 로깅해주는 것이 필요하다.

다양한 툴이 있겠으나 wireshark로 소개한다.

찾을 때 눈이 좀 아프긴 하다

일반적으로는 이런 디버깅을 경험하진 않는다.

보통 벤더사나 솔루션사에서 클라우드 서비스를 해주는 과정에서

뚫어줘야 하는 url을 정확히 알고 있어야 되는데 대충 알고 있거나 빠뜨렸을 때,

또는 그 회사에서 일반적이지 않은 방화벽 정책을 쓰느라 이상한 곳에서 막혔을 때,

혹은 방화벽 관리자가 안 풀어놓고 풀었다고 거짓말하는 거 같을 때,

그럴 때 울며 겨자먹기로 깔아서 눈을 살짝 혹사시키지만 근거를 찾을 수 있는 패킷 분석 툴이다.

회사가 엄청 크고 엄격한 곳이 아니라면 방화벽 담당자를 찾아가서,

'저 혹시 제가 이러이러한 기능이 막혀서 그러는데 제가 트리거하면 그거 리스트 같이 보고 해제할 목록 좀.....'이라고 하는 게 속편하다.

다행히도 Uipath는 나름 docs에 이 정보가 적혀있다.

https://jnaul.tistory.com/260

 

IP Resolution 관련 Cloud Orchestrator 세팅

일반적으로 Hostname을 *를 붙여 요청하면 방화벽을 해제해 주지만 간혹 IP Resolution 형태라 IP질의가 무조건 확인돼야만 방화벽을 해제해주는 사이트들이 있다. Cloud로 오케스트레이터를 설치하는

jnaul.tistory.com

https://docs.uipath.com/automation-cloud/automation-cloud/latest/admin-guide/configuring-your-firewall-for-automation-cloud

 

https://docs.uipath.com/automation-cloud/automation-cloud/latest/admin-guide/configuring-your-firewall-for-automation-cloud

 

docs.uipath.com

 

  1. 엄밀히 말하면 요구사항과 scope의 정의나 PI 등도 그 영역에 포함되지만 여기선 소스 관점에서 다뤄보려고 한다. [본문으로]

이 에러에 대해서는 2가지 접근 방법이 있다.

1. 에러에 나온 Regedit 경로 체크

2. 복구 설치 진행

----------------------------------------------------------------------------------------------------------------------------------

1. 에러에 나온 Regedit 경로 체크

1번 방법은 구글링하면 2가지가 나온다.

첫 번째는 레지스트리 엑셀 정보에 대한 경로 중 legacy를 삭제하는 방법이다.

https://forum.uipath.com/t/excel-application-scope/205256

 

Excel Application Scope 실행오류

안녕하세요 Excel 2013버전을 쓰고 있습니다. 스튜디오는 커뮤니티 버전 2020.3.0-beta.84 버전을 쓰고있습니다. Excel Application Scope 를 사용하여 Excel의 내용을 DataTable로 만들고 실행 시킬때 아래와 같은

forum.uipath.com

두 번째는 레지스트리 엑셀 정보를 변경하는 방식이 있다.

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=ksh60706&logNo=221303561194 

 

[RPA] UiPath 엑셀 오류 (System.InvalidCastException: Unable to cast COM object of type)

#RPA #UiPath #Excel #엑셀 #InvalidCastException UiPath 이용시 'Excel application sc...

blog.naver.com

 

2. 복구 설치 진행

이 방식은 프로그램 추가/제거에서 Microsoft Office를 선택하고 수정 - 복구를 진행하는 방법이다.

내 케이스의 경우 1번 케이스에 해당이 안 되는 상황에서 간헐적으로 봇 Device에서 발생하는 에러였다.

에러 메시지 자체가 복구 옵션을 진행해 보라고 했어서 어떻게 복구하는지

Excel help에서 찾아보니 저렇게 복구하라고 했다.

이래도 안 되면 엑셀을 클린 delete하고 다시 설치해야 된다고 한다.

DataTable을 받아 API로 날려야 하는 경우 JSONString으로 변경해야 되는 케이스가 생긴다.

그 경우 쓰이게 되는 pattern을 정리해 본다.

먼저 import에 Newtonsoft.Json를 포함시켜주자.

 

1. get datatable

- read range 등으로 datatable을 읽기

2. datatable column filtering

- json에 쓰이는 컬럼만 필터링

3. synchronize datatable column name to json parameter

- json parameter명으로 컬럼명을 변경

4. Json serialize

- JSONConvert.serializeObject(dtDatatable)

5. string join of array

- "{""{{jsonlist 파라미터 이름}}"":["+string.Join(",",JSONArr)+"]}"

6. input json string to api body

- body에 가공된 string을 넣어줌

 

--------------------------------------------------------------------------------

반대로 해야 되는 케이스도 있다.

1. get JsonString

2. Json deserialize

- JsonConvert.DeserializeObject(Of DataTable)(JsonString)

 

1. DataScraping이란?

Uipath의 강력한 장점 중 하나는

RPA의 Main Demand에서 많은 비중을 차지하는 '웹크롤링'을 코딩하는 생산성이 매우 좋다는 점이다.

 

그걸 가능하게 해주는 핵심적인 기능이 Data Scraping이다.

규칙성이 있는 2개의 Element만 찍어주면 자동으로 규칙성을 찾아 화면의 데이터를 datatable로 담아온다.

사용법은 굉장히 간단하게 돼있다.

첫번째 element를 클릭하고 다음 element를 클릭하면 UI의 구조적 규칙성을 찾아 알아서 구성해준다.

이것이 가능한 이유는 UI요소들의 배치가 일반적으로는 구조적 규칙성을 띄기 때문이다.

 

사용법은 이렇다.

1. 첫번째 Element 선택(Get info of ui by UI Explorer)

2. 두번째 Element 선택(Get info of ui by UI Explorer)

3.규칙성 찾음(구조적 규칙성[웹이라면 X-path])

4.특정 Selector 기준으로 규칙성에 따라 Get Data

 

2. 기준 Selector와 Metadata 조정의 필요성

다만 다음과 같은 경우에 대응이 어렵다.

A. 광고유무, 특정 트리거 유무에 따라 구조가 달라지는 경우

B. 기준이 되어야 할 요소가 화면상 특정 요소에 가려져 있는 경우

 

A는 데이터를 가져오는 기전을 생각하면 너무나 자명한 결과다.

심지어 구조적으로 같으면 해당 컬럼에 그 데이터를 넣기 때문에 잘못 가져올 수 있는 위험도 있다.

따라서 케이스에 대한 정확한 파악이 있어야 한다.

대부분 기준 selector를 잘 찾아야 해결이 된다.

필요하다면 Find Children 같은 액티비티를 이용해 동적인 기준을 잡아야 한다.

 

B는 구조상 DIV가 Wrapping 돼있어 구조를 따로 파고 들어가지 않는 이상 선택이 어려운 경우다.

기준 요소를 다시 잡는 것은 어렵지 않으나 바뀐 기준에 따라 변경된 MetaData는 새롭게 수정해줘야 한다.

 

 

3. Data Scraping MetaData의 조정

MetaData는 기준으로 잡힌 Selector에서 어떻게 데이터를 가져올지 구조를 열거한 XML 데이터다.

row 태그 : 1줄의 기준을 어디로 잡을지를 정한다.

column 태그 : 가져오는 컬럼을 정한다. 속성 exact를 1로 하면 그 구조가 안 맞는 경우 안 가져온다. 0으로 하면 없을 때, 구조가 비슷한 것을 가져온다.

name 속성 : name은 기본적으로 가져오는 컬럼명이다. 같은 구조에서 다른 attr을 가져오고 싶다면, name2='다른이름' 식으로 적어주고 해당하는 attr을 attr2='속성명'으로 적어주면 된다.

attr 속성 : metadata 구조에 해당하는 타겟으로부터 얻고자 하는 속성.

 

예시를 보자.

<extract>
	<row exact='1'>
		<webctrl tag='div' />
		<webctrl tag='article' idx='1' />
	</row>
	<column exact='1' name='예시1' attr='text' name2='예시3' attr='src'>
		<webctrl tag='div' />
		<webctrl tag='article' idx='1' />
		<webctrl tag='section' idx='1' />
		<webctrl tag='h3' idx='1' />
		<webctrl tag='span' idx='1' />
	</column>
	<column exact='1' name='예시2' attr='text'>
		<webctrl tag='div' />
		<webctrl tag='article' idx='1' />
		<webctrl tag='section' idx='2' />
		<webctrl tag='div' idx='1' />
	</column>
 </extract>

예상 결과값

dtData = ["예시1", "예시3", "예시2"

"test1", "src값", "test2222"

"test11", "src값", "test222222"]

이때 row의 첫줄 div는 기준 셀렉터의 아래 div태그를 의미한다.

기준 셀렉터 기준으로 아래에 div - article이라는 태그가 있으면 그 기준을 하나의 행 기준으로 보겠다는 의미다.

예시1 컬럼을 보면 row에 해당하는 기준 아래에

section이라는 태그, h3 태그, span 태그의 text를 가져온다.

예시2 컬럼은 row에 해당하는 기준 아래 section이라는 태그 중 2번째, 그리고 div 태그의 text값을 가져온다.

예시3 컬럼은 예시1과 같은 구조에서 src값을 가져온다.

 

 

이를 지정하기 위해선 기준 Selector의 Xpath나 Fullpath를 알아야 한다.[각주:1]

/html/body/div[2]/div[1]/div[2]/div[2]/div/div[2]/div/div/div[2]/div[2]/section/div[1]/div[1]/article/section[1]/h3/span

위에 예시를 보면 파란색 글씨가 기준 셀렉터로 잡힌 곳, 빨간색으로 표시된 곳이 row이고

그 아래에 어떤 구조의 태그로 들어가느냐를 row를 포함해서 적어주면 된다.

 

 

사용상 주의점

- 기본이 Continue On Error로 돼있기 때문에 데이터가 들어가지 않거나 selector를 못 잡아도 그냥 넘어간다.

- 기준이 되는 요소가 틀 형태로 먼저 뜨고 로딩 이후 데이터가 뿌려진다면 Retry Scope으로 체크해야 한다.[각주:2]

- 경우에 따라 metadata 자체가 조건에 맞춰 변화해야 할 수도 있다. 가령 랜덤으로 광고가 뜨면서 구조가 바뀐다든가 하는 경우도 많다.

- 버그같아 보이는데 어떤 경우 앞선 태그가 없으면 그 뒤의 정보들의 구조가 맞아도 안 들어오는 경우가 있다. 웃긴 점은 메타데이터에 쓰인 순서를 변경하면 해결되는 케이스가 존재한다. 가령 price1, price2, price3으로 크롤링 했는데 price1의 구조가 비어있는 경우 price2, price3, price1 형태로 바꾸면 잘 된다. 그럼 price2가 없는 경우 같은 현상이 일어나지 않을까 했는데 그건 잘 가져왔다. 왜 그러는지 가늠이 잘 안 되지만 안 되면 순서를 바꿔보자

  1. 브라우저 개발자 도구에서 element를 찾아 우클릭하면 copy 가능하다. [본문으로]
  2. 기준 요소만 뜨면 데이터를 가져오려고 하기 때문이다. 데이터를 기다리지 않는다. [본문으로]

DB연결 시 DSN으로 세팅하는 게 편하긴 하지만

Credential 변경 시 Device마다 각각 들어가서 바꿔줘야 한다.

그래서 규모가 커질 수록 Connection String을 설정해 Asset과 연동되도록 하는 것이 편하다.

 

"Driver={ODBC Driver 이름};Server=서버IP;Port=포트번호;Database=DB이름;Uid=아이디;Pwd=패스워드;"

 

ODBC는 일단 적절한 버전을 깔도록 하자. [보통 RPA에서는 32비트로 연결되므로 5점대 버전이 안정적이다]

ODBC 설정에 들어가서 '추가'를 누르면 다음과 같이 뜬다.

 

ODBC 선택창

여기서 뜨는 '이름'을 Driver에 적어주자.

-----------------------------------------------------------------------------------------

혹시나 DB 종류가 다른 경우, 가령 오라클이면

Oracle ODBC를 깔고 Oracle ODBC connection string을 쳐서 찾아보면 된다.

다만 Driver name은 웬만해선 지정해줘야 돌아가니 체크

+ Recent posts