지식메모




자동화를 하면 항상 새 크롬창을 띄웠는데 현재 실행 중인 크롬 창에서 실행할 수는 없을까해서 검색해본 결과


무조건 한번은 새로 크롬을 새로 띄워야 한다는 결론에 도달.


그리고 그 크롬에서 적용 할 수 있었다.


첫번째 해야할 것은 (크롬드라이버 다운은 필수)


cmd에서 디버그용? 크롬을 실행시켜야 한다


chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\selenum\AutomationProfile" 


이걸 cmd에서 실행해보면 크롬이 실행된다.


안된다면 C:\Program Files (x86)\Google\Chrome\Application\ 이 경로로 이동해서 실행해보거나


환경변수에 위 경로를 추가해준다.



이 크롬으로 계속 재활용할 수 있다.


이제 이걸 자바 코드 내에 cmd 실행을 시킨다음 실행해주면 된다.


참고로 코드 내에서 실행할 때는 완전한 경로로 해주어야 실행이 된다.


 Runtime.getRuntime().exec("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe --remote-debugging-port=9222 --user-data-dir=\"C:/selenum/AutomationProfile\"");


위 코드를 먼저 실행해 준 다음


ChromeOptions options = new ChromeOptions();

options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");

driver = new ChromeDriver(options); 


크롬 옵션을 추가해주어 실행된 크롬창을 사용하도록 지정해준다.(9222포트는 위 실행명령어 포트와 동일)



전체적인 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Automation {
 
    private static WebDriver driver;
 
    @BeforeClass 
    public static void setUp() throws Exception { 
        System.setProperty("webdriver.chrome.driver""C:\\chromedriver.exe");
            
        Runtime.getRuntime().exec("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe --remote-debugging-port=9222 --user-data-dir=\"C:/selenum/AutomationProfile\"");
 
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("debuggerAddress""127.0.0.1:9222");
        driver = new ChromeDriver(options);
        
        System.out.println(driver.getTitle());
        driver.manage().window().maximize();
        driver.get("https://www.naver.com");
        
    }
}
cs



 자동화 실행 후 현재 실행중인 크롬에서 확인해보려면  Runtime.getRuntime().exec 코드를 주석처리하고 실행하면 확인해볼 수 있다


주석처리를 안하면 실행할 때마다 새로운 크롬이 생성된다.







셀레니움으로 자동화를 하다보면 작업관리자에 chromedriver.exe가 수두룩하게 누적되어 있는 걸 볼 수 있다


이게 쌓이다보면 메모리를 상당히 잡아먹고 있는데 그래서 자동화가 한번 끝나면 프로세스를 종료하도록 하였다.

셀레니움에서 프로레스를 죽이는 기능이 있다고 하는데 이제 사용하지 않는 기능이라고 문서에 나와있었다




그렇다면 다른 방법으로 메소드를 다시 만들었을 것 같은데 아직 찾지 못했고 일단 급한대로 프로세스 죽이는 코드를 적용했다.



python 파이썬

- cmd에서 pip install psutil 로 설치 필수
1
2
3
4
5
6
7
import psutil 
 
for proc in psutil.process_iter():
    # check whether the process name matches
    if proc.name() == PROCNAME:
        proc.kill()
 
cs



java 자바에서 사용


1
Runtime.getRuntime().exec("taskkill /F /IM chromedriver.exe /T");
cs



자동화 코드 이후에 추가해주면 chromedriver.exe가 없어지는 걸 볼 수 있었다.




영상 도입부에 손글씨 애니메이션을 사용해보고 싶어 유튜브를 검색해본 결과 

손글씨 애니메이션 효과에는 Stroke 라는 기능이 필수적이라는 걸 알게 되었습니다.


Stroke 키워드로 검색해보면 더 자세한 해외 유튜버들의 영상이 있으니 참고 하시면 좋을 것 같습니다.


사실 다 영어라서 영상만 보고 속성으로 익혀서 자세한 건 잘 모르지만

잊어먹을까봐 기록해 둡니다.






https://yonoo88.tistory.com/1210


위 링크에서 만들었던 로그인 창은 암호 입력시 암호가 가려지지 않는다.


암호를 가리기 위해서는 다음 코드가 필요하다.


self.lineEdit_PW.setEchoMode(QtWidgets.QLineEdit.Password)


이 코드를 암호 입력 코드에 추가해준다.





아니면 코드를 추가하지 않고 Qt designer 에서 GUI 를 구성할 때 속성을 변경해주면 자동으로 코드가 추가되어 있다.



echoMode를 password로 변경해주면 다음과 같이 암호가 가려진다.









다빈치 리졸브 15에서 특정 사물이나 얼굴에 모자이크가 따라다니게 하는 방법입니다.





다빈치 리졸브 14를 쓰다가 이제서야 15를 설치해보았다


설치하고 어떤 효과과 있나 살펴보았는데 타이틀 효과가 추가된게 있었다.


다양한 3D 효과도 제공되고 있어서 어떤 효과가 있는지 살펴보았다



먼저 

심플한 타이틀 효과 12가지



아래 자막이 타이틀 효과 이름이다.






Lower 3rd 텍스트 효과 10가지







3D Lower 3rd 텍스트 효과 9가지







3D 타이틀 효과 14가지





이처럼 다빈치 리졸브 15에서는 14에서는 없었던 많은 타이틀 및 텍스트 효과를 제공하고 있다


물론 세부 수치 조절로 글자 색상 및 효과를 조절 가능하다


하지만 나같은 초보자들에게는 어려운 작업이기 때문에 기본값으로만 써도 충분할 것으로 생각한다.


기본적으로 제공하는 도구를 잘 쓰는 것도 하나의 능력이라 생각되기 때문에 

무슨 기능이 있는지 잘 찾아보는 습관을 길러야겠다.


단 감안해야할 점은 

3D 효과의 경우 컴사양이 좋아야 한다. 사양이 딸리면 작업환경에서 영상효과가 끊겨서 눈으로 확인이 어렵다

위 영상도 1분남짓 영상인데 인코딩만 10분이 걸렸다..


영상편집시 좋은 컴 사양은 필수!







해외 고객센터에 전화를 걸 일이 생겨서 국제전화비용 때문에 이거저거 알아보았다

국제전화 카드를 사서하거나 핸드폰 00700 같은 국제전화 번호를 사용하는 방법이 있었지만

카드는 소액구매가 불가능하고 최소 2만원? 부터 구매가 가능했다.

00700은 SKT 고객센터에 물어보니 분당 천원꼴이지만 3분 통화시 3분 추가 무료통화가 가능하댄다

그래서 요금이 걱정되면 6분 통화 후 끊고 다시 걸어 3분+추가3분 의 혜택을 받는 식으로 해야한다고 한다.

넘나 번거로운 것..


그래서 뭐 없나 찾아보다 발견한 OTO무료국제전화


무료 라고 하지만 무료는 아니다


이말인 즉슨 국제전화를 국제전화 비용이 아닌 국내통화료로 이용할 수 있다는 뜻이다.

주요기능 설명이다



[주요기능]

★ 무료국제전화

- 한국에서는 미국, 캐나다, 중국, 일본 등 94개국에 대해서 무료로 국제전화를 사용하실 수 있습니다. 

(가입하신 통신사 요금제의 부가통화 분수가 차감되는 방식으로, 잔여 부가통화 분수가 없을 시 통신사 요금제에 따른 국내통화료가 발생할 수 있으며, 별도의 국제전화 요금은 발생하지 않습니다.)


★ 왜 OTO 무료국제전화여야 하는가?

1. OTO무료국제전화는 국제전화 비용이 절대로 발생하지 않아 무료국제전화입니다.

2. 국제전화를 내 휴대전화 국내음성통화료로 이용할 수 있으니 걱정이 없습니다. 

3. 주요 국가들만 무료인 다른 서비스와 달리, OTO무료국제전화는 94개국에 무료통화를 제공하고 있습니다. 


간단히 국제전화를 국내통화료로 이용할 수 있다고 한다.


밑져야 본전 한번 해보기로 하였다.


앱 설치 후 국가선택을 하면 자동으로 국가번호가 적용되고 이어서 전화번호를 누르면 된다

(단 국제전화전용 번호여야 한다. 해당 국가의 국내번호는 불가능)



영어로 통화를 해야한다니 굉장히 긴장이 되었지만 심호흡을 한 후

번호를 누르고 통화를 누르면 아래와 같은 화면이 나온다



그리고 곧 국내 통화화면으로 바뀐다. 

안내에 따라 다이얼을 눌러야 한다면 이 화면에서 누르면 된다.



이제 남은 건 본인의 리스닝 실력이다.

내가 할 말은 번역기로 이미 다 적어놓았지만 문제는 듣는거다.


어림짐작으로 어케어케 통화를 마쳤다.

총 통화는 5분정도 되었다.

용케 알아 들어준 상담사에게 감사의 뜻을 전한다.


통화를 마치고 요금 확인을 해보았다.

망외 통화 100분에서 통화가 차감되었다.

실시간 요금을 봐도 국제전화 통화료는 나오지 않았다.

사실상 무료 국제전화를 한 셈이다.

무제한 전화요금제를 쓰거나 잔여 통화가 남아있다면 국제전화를 무료로 쓸 수 있는 것이다!




통화 품질 후기는

어떤 원리인지는 모르겠지만 초반에는 다이얼도 잘 안먹히는 것 같았고 끊김도 있었다.

겨우 상담사 연결을 했는데 내 목소리가 안들리는 것 같았다.

그래서 2번이나 전화를 끊겼다 (내가 끊은게 아님)

그러다보니 총 통화시간은 10분정도 되었다.


이후 통화에서는 잘들렸으나 약간의 딜레이가 있는 듯 하다.

딜레이를 고려해서 천천히 말하고 하면 무리없이 통화가 가능하다.


당장 급하고 짧은 시간만 통화할 일이 생긴다면 유용한 서비스라고 생각한다.

OS High Sierra 10.13.4

 Xcode 9.4.1


코드 한줄 삭제 단축키 만들기


Xcode > Preferences > key Bindings 진입 후 

"delete line"으로 검색하면 단축키가 설정되어 있지 않은데 설정할 수 있다.



습관대로 컨트롤 + D로 설정

맥 키 익히는 것도 일이다...



GUI 구성하기

Qt designer로 생성한 .ui 파일 파이썬 .py로 변환

http://yonoo88.tistory.com/1209


GUI 구성상태


기능 : ID와 PW 입력 후 시작버튼을 누름 > 동작 완료 후 listWidget에 로그인 성공 표시


아래 코드를 보면 UI 객체 명 별로 코드가 구성되어 있다

핵심은 시작 버튼에 이벤트 처리를 해주는 것. 시작 버튼 객체명은  startButton  이다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 
from PyQt5 import QtCore, QtGui, QtWidgets
from selenium import webdriver
import time
 
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(180234)
 
        self.listWidget = QtWidgets.QListWidget(Dialog)
        self.listWidget.setGeometry(QtCore.QRect(2016014161))
        self.listWidget.setObjectName("textBrowser")
 
        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(80101616))
        self.label.setObjectName("label")
 
        self.label_2 = QtWidgets.QLabel(Dialog)
        self.label_2.setGeometry(QtCore.QRect(80702116))
        self.label_2.setObjectName("label_2")
 
        self.startButton = QtWidgets.QPushButton(Dialog)
        self.startButton.setGeometry(QtCore.QRect(501307523))
        self.startButton.setObjectName("startButton")
 
        self.lineEdit_ID = QtWidgets.QLineEdit(Dialog)
        self.lineEdit_ID.setGeometry(QtCore.QRect(303011320))
        self.lineEdit_ID.setObjectName("lineEdit_ID")
 
        self.lineEdit_PW = QtWidgets.QLineEdit(Dialog)
        self.lineEdit_PW.setGeometry(QtCore.QRect(309011320))
        self.lineEdit_PW.setObjectName("lineEdit_PW")
 
        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
 
#startButton 클릭시 autoExcute 함수 수행
        self.startButton.clicked.connect(self.autoExcute)
 
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog""Naver Login"))
        self.label.setText(_translate("Dialog""ID"))
        self.label_2.setText(_translate("Dialog""PW"))
        self.startButton.setText(_translate("Dialog""시작"))
 
 #셀레니움 동작 코드 함수 autoExcute 생성
    def autoExcute(self):
        driver  = webdriver.Chrome('C://chromedriver.exe')
        driver.implicitly_wait(3)
        driver.get('http://www.naver.com')
        driver.maximize_window()
        id = self.lineEdit_ID.text()
        pw = self.lineEdit_PW.text()
        driver.find_element_by_class_name('lg_local_btn').click()
        driver.find_element_by_id('id').send_keys(id)
        driver.find_element_by_id('pw').send_keys(pw)
        driver.find_element_by_class_name('btn_global').click()
        time.sleep(3)
        driver.close()
#listWidget에 로그인 성공 표시
        self.listWidget.addItem('로그인 성공')
        # self.addItem()
 
 
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())
 

cs


코드를 실행시킨 후 아이디와 암호 입력 > 시작을 누르면 로그인 자동화가 진행되고 끝나면 로그인 성공 텍스트가 나타난다






아래와 같은 ui를 만든 후 naver.ui로 저장

UI 구조 - 각 클래스와 객체명 


naver.ui 를 열어보면 xml형태로 작성되어 있음


이 파일을 파이썬 .py 파일로 변환하기

파일있는 폴더경로로 이동해서 cmd 창에서 pyuic5 -x naver.ui -o naver.py  실행

그럼 naver.py 생성

naver.py를 열어보면

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# -*- coding: utf-8 -*-
 
# Form implementation generated from reading ui file 'naver.ui'
#
# Created by: PyQt5 UI code generator 5.11.2
#
# WARNING! All changes made in this file will be lost!
 
from PyQt5 import QtCore, QtGui, QtWidgets
 
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(158234)
        self.textBrowser = QtWidgets.QListWidget(Dialog)
        self.textBrowser.setGeometry(QtCore.QRect(1016014161))
        self.textBrowser.setObjectName("textBrowser")
        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(70101616))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(Dialog)
        self.label_2.setGeometry(QtCore.QRect(70702116))
        self.label_2.setObjectName("label_2")
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(401307523))
        self.pushButton.setObjectName("pushButton")
        self.lineEdit_ID= QtWidgets.QLineEdit(Dialog)
        self.lineEdit_ID.setGeometry(QtCore.QRect(203011320))
        self.lineEdit_ID.setObjectName("lineEdit")
        self.lineEdit_PW= QtWidgets.QLineEdit(Dialog)
        self.lineEdit_PW.setGeometry(QtCore.QRect(209011320))
        self.lineEdit_PW.setObjectName("lineEdit_2")
 
        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
 
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog""Dialog"))
        self.label.setText(_translate("Dialog""ID"))
        self.label_2.setText(_translate("Dialog""PW"))
        self.pushButton.setText(_translate("Dialog""시작"))
 
 
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())
cs

위와 같이 자동으로 코드로 변환되어 있음. 이 코드 안에서 이벤트를 연결하여 기능을 구현할 수 있음


+ Recent posts

티스토리 툴바