Object Click은 Object의 속성값을 인식해 Click 동작을 수행합니다.

 

문제

연합뉴스 우측에 있는 값을 클릭하여 연합뉴스속보에 접속한다.


Object Click 이벤트를 가져다 놓고, Capture합니다.

 

하지만 "13년 걸린 강제징용 대법 판결, 2년8개월만에 뒤집혀"라는 문구 대신 다른 문구일시, 정상 작동하지 않는 결과가 나타났습니다.

 

Main Context의 값을 확인해 보니, 8번 인덱스와 9번 인덱스의 NAME에서 고정적인 텍스트 값을 발견할 수 있었습니다.

이 값을 {*}을 활용하여 동적인 이벤트로 변경해 줍니다.

8번 index와 9번 index의 값을 변경해주니 동적으로 Object Click이 수행되는 것을 확인할 수 있었습니다.

 

{*}는 "모든 문자열을 포함한다" 라는 뜻을 가집니다.

따라서 적절한 곳에 *를 사용하면 이벤트를 동적으로 처리할 수 있습니다.

Image Check는 해당되는 이미지가 존재하는지의 여부를 체크합니다.

만약 존재한다면 _RESULT에 TRUE를, 미존재시 FALSE를 반환합니다.

 

주로 로딩 시간이 가변적인 홈페이지 또는 팝업창의 여부 등을 체크하는데 사용됩니다.

 

문제

해당 이미지가 존재하면 True를, 존재하지 않으면 False를 나타내는 Message Box를 생성한다.


 

if Then의 Main Context

실행결과

Image Click은 해당되는 이미지를 클릭하는 업무를 수행합니다.

 

해당 이미지가 HTML 또는 Object를 이용하지 못할경우에도 사용됩니다.

 

문제

NAVER 홈페이지에서 '증권'을 클릭하여 네이버 금융 페이지에 접속하는 이벤트를 수행한다.


 

Event Componets에서 Image Click을 선택한 후 Event List에 더블클릭 또는 드래그하여 추가합니다.

 

 

Event Context의 Main Context에서 Capture를 눌러 캡처할 이미지를 선택합니다.

캡처가 정상적으로 이루어졌다면 Main Context에 캡처한 부분이 나타납니다.

해당 이벤트를 더블 클릭 또는 Play Script(F5)를 클릭하면 정상적으로 실행됩니다.

문제

'yes24' 홈페이지에 접속하여 RPA 검색 후 책이름, 저자, 출판사를 엑셀에 저장한다.

 

 

실행영상

 

책 스크래핑.zip
0.01MB

- 오류 발생시 Script Code를 이용하여 알림

- 'YES24' 홈페이지 접속

- 책 정보를 HTML Get Value를 이용하여 변수에 저장

- 저장된 내용을 Excel Script를 이용하여 불러옴

- 입력된 내용을 새로운 Excel Script를 생성하여 저장

 

문제

주 1회 조회를 수행하여 Weekly 시트에 기사 제목을 입력하고 중복기사를 제거한 뒤 Essential 시트에 내용을 쌓는다.

 

조건

검색창에 RPA 입력

상세검색 1주

기사 100건 보기

제목, 언론사, 날짜, URL의 데이터 취득

 

해설

Transaction은 초기처리, 주처리, 종료처리 세 단계로 나누어 작성하였습니다.

초기처리에는 Script Code를 사용하여 파일 경로를 변수에 설정하였습니다.

주처리는 작성한 모듈을 Custom Module Item을 통해 불러와 사용하였습니다.

 

Custom Module 분석

Custom Module에 이러한 주처리 과정을 작성하였습니다.

 

01. BigKinds 접속 및 검색

- 메세지 Script Code를 통해 에러 발생시 변수에 string값을 입력하여 에러 메세지를 개발자에게 알립니다.

- Process Kill을 통해 열려있는 IE를 종료합니다.

- Internet Browswer를 통해 bigkinds에 접속합니다.

- Active Window를 통해 bigkinds 창을 활성화 시켰습니다.

- Object SetValue를 통해 RPA를 입력하는 과정을 수행하였습니다.

- 세부 설정은 Image Click을 이용하였고, 만약 세부사항이 설정되지 않았을 경우 Loop를 통해 재수행합니다. 설정이 정확히 이루어진 경우 Loop Break를 통해 Loop를 종료하고 다음 event로 넘깁니다.

- 적용하기 버튼을 클릭합니다.

 

02. 기사 데이터 가져오기

- 원하는 창이 열려있는지 Image Check를 통해 확인합니다. 만약 열려있으면 설정을 시작합니다. '100건씩 보기'가 클릭되지 않았을 시 다시한번 Loop합니다. 정상수행시 Loop Break를 통해 종료합니다.

- 마지막 값을 HTML GetValue를 통해 저장합니다. string 형태로 저장되기 때문에 int로 형변환하는 과정을 거쳤습니다. 이것은 LoopCount에 사용됩니다.

- 가져온 LoopCount (intLastCount)만큼 값을 가져오는 Loop를 수행합니다. 제목, 언론사, 날짜, URL의 데이터를 취득합니다. 가져온 데이터는 list에 저장합니다(역순으로)

 

02-1. X Click

02번 모듈의 Exception Loop를 사용하기 위해 모듈을 따로 사용하였습니다.

 

03. 엑셀 정리

정제가 되지 않은 데이터의 내용을 엑셀의 Weekly에 붙여넣는 과정을 구현하기 위해 Excel Script를 사용하였습니다.

04. 중복기사 제거

데이터를 정제하고 Essential 시트에 값을 넣기 위한 Excel Script를 작성하였습니다.

 

간략한 코드를 첨부합니다.

더보기

for(a=2;a<xl.GetLastRowIndex();a++)
        {    
            
            /***********************************************************************************************************/
            str1=xl.GetOneCellValue("D" + a);
            str1=Regex.Replace(str1, @"[^a-zA-Z0-9가-힣_]""", RegexOptions.Singleline);
            lstStr1.Clear();
            
            for(b=0;b<=str1.Length-2;b++)
            {    
                lstStr1.Add(str1.Substring(b,2));
            }
            
            /***********************************************************************************************************/
            for(c=a+1;c<=xl.GetLastRowIndex();c++)
            {    
                str2 = xl.GetOneCellValue("D" + c);
                str2=Regex.Replace(str2, @"[^a-zA-Z0-9가-힣_]""", RegexOptions.Singleline);
                lstStr2.Clear();
                
                /***********************************************************************************************************/
                //여기부터 str2의 처리부분
                for(d=0;d<=str2.Length-2;d++)
                {    
                    lstStr2.Add(str2.Substring(d,2));
                }
                
                /***********************************************************************************************************/
                //중복되는 만큼 서로 비교하기 위해 e에 최소 Count값을 저장
                if(lstStr1.Count>lstStr2.Count)
                    e = lstStr2.Count;
                else
                    e = lstStr1.Count;
                
                /***********************************************************************************************************/
                //최소 Count값만큼 lst index를 비교하여 교집합과 합집합으로 lst에 저장
                lstSMA.Clear();
                string tmp1="";
                string tmp2 = "";
                
                //교집합
                for(f=0;f<e;f++)
                {    
                    tmp1 = lstStr1 [f];
                    
                    for(int m=0;m<e;m++)
                    {
                        tmp2 = lstStr2 [m];
                        
                        if(tmp1.Equals(tmp2))
                        {    
                            lstSMA.Add(tmp2);
                        }    
                    }
                }
                
                
                /***********************************************************************************************************/
                lstCUP.Clear();
                
                //합집합
                for(g=0;g<e;g++)
                {    
                    if(!lstCUP.Contains(lstStr1[g]))
                    {    
                        
                        lstCUP.Add(lstStr1[g]);
                    }
                    
                    if(!lstCUP.Contains(lstStr2[g]))
                    {    
                        
                        lstCUP.Add(lstStr2[g]);
                    }
                }
                
                /***********************************************************************************************************/
                //교집합과 합집합의 계산
                float sma, cup;
                
                sma = lstSMA.Count;
                cup = lstCUP.Count;
                
                
                floatDiv = (sma / cup);
                
                
                if(floatDiv>0.1)
                {    
                    xl.DeleteRow(c);
                    
                    c--;
                }
            }    
        }
        
        for(int del=2;del<=xl.GetLastRowIndex();del++)
        {    
            lstDelTitle.Add(xl.GetOneCellValue("D" + del));
            lstDelURL.Add(xl.GetOneCellValue("E" + del));
            
        }

Linq등을 이용하면 손쉽게 처리할 수 있는 부분이었지만 현재 사용할 수 있는 언어를 통해 직접 해결하고 싶어 C언어의 방식으로 구현하였습니다.

 

중복기사 제거를 위해 제목의 유사도를 검색하는 것이 가장 좋을것 같아 유사도 제거 방식으로 구현하였습니다.

자카드 유사도를 참고하여 직접 작성해 보았습니다.

 

위 코드는 가져온 글자를 두글자씩 나누어 합집합과 교집합으로 계산한 후 나누어 유사도를 계산하는 알고리즘을 구현하였습니다.

 

해당 알고리즘을 통해 10% 이상 일치시 해당 row를 제거하는 방식으로 정제를 진행하였습니다.

 

05. 로그인 후 게시글 작성 

1. 열려있는 IE 종료

2. 사이트 접속

3. 창 활성화 후 로그인 및 아이디, 패스워드 입력

4. 카테고리 클릭 후 게시글을 작성하는 로직 구현 

 

 

개선 방향

- Exception Loop의 정확한 사용법을 숙지한 후 사용

- 알고리즘의 변수명 수정

- Wait Time의 사용 줄일수 있는 방법 (무자비한 사용은 시간낭비를 초래하기 때문)

- 알고리즘 구현시 불필요한 코딩을 줄이기 위해 다양한 함수 활용

- 최적화

 

 

 

실행영상

 

문제

가장 최근에 올라온 뉴스를 한개씩 자동으로 띄워주는 RPA를 작성한다. 페이지의 확인 시간은 20~30초로 하고, 한 페이지의 기사를 띄운 후 종료한다.

 

해설

1. 메세지 Script Code를 이용해 에러 발생시 메세지를 출력한다.

2. Process Kill을 이용해 실행되기 전 열려있는 익스플로어 창을 닫는다.

3. 'bigkinds'홈페이지에 접속하여 최근 기사를 클릭하고, 창 로딩 여부를 image Check를 이용하여 확인한다. 만약 창이 실행되었다면 Loop Break를 통해 빠져나온다.

4. Loop를 통해 기사 하나하나씩 창을 띄우는 과정을 수행한다. 

HTML SetValue를 이용하여 클릭하고, Key Typing으로 Page UP, Page Down하여 기사 내용을 확인할수 있도록 한다.

본문은 20초동안 읽을 수 있다.

5. Script Code를 통해 HTML SetValue의 속성값을 증가시켰다.

 

 

개선 사항

종료 후 홈페이지를 닫는 과정 추가

20초 후 자동으로 다음 페이지로 넘어가는 것에 대한 방안 (본래 Message Box로 처리하려 하였지만 매번 클릭해야되는 불편함이 있었다.)

 

 

실행영상

 

 

문제

'외교부 해외안전여행' 사이트에 접속하여 단계별 여행경보 3단계 및 4단계의 데이터를 저장해 엑셀에 붙여넣기한다. 

 

 

해설

g

1. Internet Browser로 '외교부 해외안전여행' 사이트에 접속한다.

2. HTML GetValue를 이용하여 변수에 데이터를 저장한다.

3. Clipboard Write를 이용하여 저장한 데이터를 Clipboard로 저장한다.

4. Excel File을 Open한다.

5. Active Window를 통해 해당 창을 활성화시키고 Key Typing을 이용하여 엑셀에 붙여넣기 하였다.

6. Excel Save와 Close를 이용해 Excel을 저장하고 종료했다. 

7. Process Kill을 통해 열려있는 Explorer를 종료하였다.

 

개선

- 변수에 저장하는 방법이 아니라 DataTable 또는 List를 활용하는 방법 추가

- Excel Script를 이용하여 한번에 처리하는 방법

 

 

실행영상

 

문제

상근이는 매일 아침 알람을 듣고 일어난다. 알람을 듣고 바로 일어나면 다행이겠지만, 항상 조금만 더 자려는 마음 때문에 매일 학교를 지각하고 있다.

상근이는 모든 방법을 동원해보았지만, 조금만 더 자려는 마음은 그 어떤 것도 없앨 수가 없었다.

이런 상근이를 불쌍하게 보던, 창영이는 자신이 사용하는 방법을 추천해 주었다.

바로 "45분 일찍 알람 설정하기"이다.

이 방법은 단순하다. 원래 설정되어 있는 알람을 45분 앞서는 시간으로 바꾸는 것이다. 어차피 알람 소리를 들으면, 알람을 끄고 조금 더 잘 것이기 때문이다. 이 방법을 사용하면, 매일 아침 더 잤다는 기분을 느낄 수 있고, 학교도 지각하지 않게 된다.

현재 상근이가 설정한 알람 시각이 주어졌을 때, 창영이의 방법을 사용한다면, 이를 언제로 고쳐야 하는지 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에 두 정수 H와 M이 주어진다. (0 ≤ H ≤ 23, 0 ≤ M ≤ 59) 그리고 이것은 현재 상근이가 설정한 놓은 알람 시간 H시 M분을 의미한다.

입력 시간은 24시간 표현을 사용한다. 24시간 표현에서 하루의 시작은 0:0(자정)이고, 끝은 23:59(다음날 자정 1분 전)이다. 시간을 나타낼 때, 불필요한 0은 사용하지 않는다.

 

출력

첫째 줄에 상근이가 창영이의 방법을 사용할 때, 설정해야 하는 알람 시간을 출력한다. (입력과 같은 형태로 출력하면 된다.)

#include <iostream>
using namespace std;

int main()
{
    int h, m;
    cin >> h >> m;

    m -= 45;

    if (m < 0)
    {
        m += 60;
        h = (h + 24 - 1) % 24;
    }

    cout << h << m;

    return 0;
}

 

문제

흔한 수학 문제 중 하나는 주어진 점이 어느 사분면에 속하는지 알아내는 것이다. 사분면은 아래 그림처럼 1부터 4까지 번호를 갖는다. "Quadrant n"은 "제n사분면"이라는 뜻이다.

예를 들어, 좌표가 (12, 5)인 점 A는 x좌표와 y좌표가 모두 양수이므로 제1사분면에 속한다. 점 B는 x좌표가 음수이고 y좌표가 양수이므로 제2사분면에 속한다.

점의 좌표를 입력받아 그 점이 어느 사분면에 속하는지 알아내는 프로그램을 작성하시오. 단, x좌표와 y좌표는 모두 양수나 음수라고 가정한다.

 

입력

첫 줄에는 정수 x가 주어진다. (−1000 ≤ x ≤ 1000; x ≠ 0) 다음 줄에는 정수 y가 주어진다. (−1000 ≤ y ≤ 1000; y ≠ 0)

 

출력

점 (x, y)의 사분면 번호(1, 2, 3, 4 중 하나)를 출력한다.

 

#include <iostream>
using namespace std;


int main() {

int a,b;

cin >> a>>b;

if (a > 0 && b > 0)
cout << 1;
else if (a < 0 && b>0)
cout << 2;
else if (a < 0 && b < 0)
cout << 3;
else
cout << 4;
}

문제

연도가 주어졌을 때, 윤년이면 1, 아니면 0을 출력하는 프로그램을 작성하시오.

윤년은 연도가 4의 배수이면서, 100의 배수가 아닐 때 또는 400의 배수일 때이다.

예를 들어, 2012년은 4의 배수이면서 100의 배수가 아니라서 윤년이다. 1900년은 100의 배수이고 400의 배수는 아니기 때문에 윤년이 아니다. 하지만, 2000년은 400의 배수이기 때문에 윤년이다.

 

입력

첫째 줄에 연도가 주어진다. 연도는 1보다 크거나 같고, 4000보다 작거나 같은 자연수이다.

 

출력

첫째 줄에 윤년이면 1, 아니면 0을 출력한다.

 

#include <iostream>
using namespace std;


int main() {

int year;

cin >> year;

if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
cout << true;
else
cout << false;
}

+ Recent posts