프롤로그

한 달 동안인가? 열심히 Python 코드를 작성 한 후, 여러 가지 테스트 끝에 Release를 실시했었다. 파이썬이 깔려 있지 않은 PC에서도 실행이 가능하도록 Pyinstaller로 Exe 파일로 변환해서 말이다.

그런데 지난 주에 내 노트북 SSD가 문제가 생겨 부팅이 되지 않는 것이었다. 모든 데이터가 순식간에 다 날라가 버린것이다. 물론 그 Python 코드도 말이다.

구글링을 통해 열심히 복구하기 위해 노력했지만, 데이터 복구 업체가 괜히 있는게 아니라는 생각이 들었다. 복구와 같은 고급 기술은 몇날 몇일을 구글링해도 나와있지 않았다. 물론 간단한 복구 툴소개 및 진단 방법에 대해서는 적지 않은 자료가 있지만 말이다.

결국 구글링은 포기하고 데이터 복구 업체를 컨택해서 복구 비용을 물어 보았지만, SSD의 경우는 일반 HDD 대비 복구 비용이 3배 이상은 비쌌다. 일반 HDD의 경우 1TB 용량은 20~30만원선이었지만, SSD의 경우 1TB 용량은 60~80만원이었다.

고민끝에 Cloud 서비스들에 그나마 조금씩 공유했던 자료들을 긁어 모으기 시작했고, 고생 고생 끝에 그럭저럭 데이터들을 복구할 수 있었다.

하지만 한 달 동안 고생하며 짰던 Python 코드는 복구 할 수 없었다. 하지만 천만 다행으로 Pyinstaller로 Release 했던 Exe 파일하나를 찾을 수 있었다.

자, Pyinstaller로 만든 파이썬 exe 파일을 원래 파이썬 소스 파일인 py로 변환하기만 하면 된다 !!!

 

어떻게 하면 될까?

3일 동안 틈나는 대로 구글링을 하여 Exe 파일을 py 파일로 변환하는 것을 찾아보았다. 외국의 사례에서도 나와 같은 경험을 한 사람들이 꽤나 있었다. 하지만, 의외로 명쾌한 답을 찾기는 어려워 보였다. 하지만 다행이도 Jako 님의 Blog를 통해 좀 더 확실히 솔루션에 접근을 할 수 있었다.

https://klonic.tistory.com/115

 

pyinstaller로 변환 된 exe 파일 디컴파일 시키기

Pyinstaller 디컴파일 pyinstaller란 .py 파일을 .exe 파일로 변환할 때 쓰는 프로그램 입니다. pip install pyinstaller로 설치가 가능하고 설치가 되고나면 윈도우 커맨드에서 pyinstaller 라는 명령어로 실행..

klonic.tistory.com

위의 Blog의 내용을 바탕으로 본인이 실습한 내용을 다음과 같이 설명하고자 한다.

 

준비

다음과 같은 Tool이 필요하다.

 

exe 파일을 py 파일로 변환하기

준비가 끝마쳐졌으면, 파이썬 exe 파일을 작업을 할 폴더로 이동을 한다(참고로, 본인의 경우 "findgoodprice_naver.exe" 파일이며, 작업 폴더는 "D:\04_Code" 이며, 또한 Visual Studio Code를 Editor로 사용하고 있다).

하기와 같이 Visual Studio Code(VSC)의 Terminal 창에서 작업 폴더로 이동한 후, 미리 Down 받은 Pyinstxtractor.py을 실행하여 exe 파일을 pyc 파일로 변환한다.

python pyinstxtractor.py findgoodprice_naver.exe

참고로, 파이썬으로 만든 exe 파일의 파이썬 버젼과 동일한 버젼의 파이썬을 이용해야 한다.

본인의 경우 exe 파일은 3.76으로 작성을 하였으며, 새로 설치한 파이썬도 3.76 버젼이다.

만약 버젼이 맞지 않은 경우 하기와 같이 Warning 메시지가 뜬다.

프롤로그

자동화 스케쥴링을 윈도우에서 제공하는 스케쥴러를 이용하여 여러번 시도해 보았으나 내가 마음먹은대로 동작시키는데 실패를 하고, 기억 저편에 넣어 두었다.

그러던차에, Cron이라는 프로그램을 접하게 된 후, 자동화 프로그램을 스케쥴링 하는데 성공하였다.

그래서 이번에는 Cron이라는 프로그램 설치 및 간단한 사용법을 알아보기로 한다.

프로그램 다운로드

프로그램 다운로드를 위해서는 다음 웹페이지를 방문하여 다운 받으면 된다.

http://www.nncron.ru/download.shtml

 

nnSoft: download

com_ports.spf 1k 12 Dec 2008 Tests the specified COM-port and returns TRUE if the port is free or returns FALSE if the port is busy (used by some devices or applications). crc32.spf 1k 12 Dec 2008 Generates a string, that contains checksum (crc32) of a spe

www.nncron.ru

아래 발췌한 웹페이지 그림에서와 마찬가지로 'nncronlt117.exe' 파일을 다운받으면 된다(참고로 본인은 Win10 환경이다).

다운로드 완료 후 그 파일을 실행한다.

Cron 파일 다운로드 완료

실행을 하면 다음과 같이 언어를 선택할 수 있는 창이 뜬다. '영어'와 '러시아어' 2가지만 지원한다.

그래서 '영어'를 선택하면 된다.

Cron 파일 설치 - 언어선택

그 다음 화면에서 동의('Agree')를 선택 후 진행.

Cron 파일 설치 - Agree

인스톨 옵션 창에서 현재 상태 그대로 진행을 하기위해 'Next'를 누른다.

Cron 파일 설치 - 인스톨 옵션

경로를 별도로 지정하지 않고 'Install'을 눌러 다음 단계로 진행.

Cron 파일 설치 - 경로지정

인스톨이 완료 되면 'Close'를 눌러 작업을 마친다.

Cron 파일 설치 - 완료

Cron 프로그램 실행

프로그램 설치 경로를 변경하지 않고 프로그램을 정상적으로 설치 하였다면, "C:\Program Files (x86)\cron" 경로에 다음과 같이 설치된 파일들을 확인 할 수 있다.

Cron_설치폴더

Cron 프로그램을 실행하는 방법은 exe 파일을 실행하지 않고, cron.tab 파일을 수정하는 것으로 실행이 가능하다. cron.tab을 수정하기 위해서는 편집기로 파일을 열어 수정을 하는데, 프로그램을 '권리자 권한으로 실행' 실행해야지만 파일저장이 가능하다.

먼저, Win10에서 Search 메뉴를 이용하여 wordpad를 '권리자 권한으로 실행'을 한다.

워드패드_권리자권한으로실행

'관리자 권한으로 실행' 후에 '파일' → '열기'를 선택 하여, "C:\Program Files (x86)\cron" 경로에서 cron.tab 파일을 열어서 수정을 하면 된다.

워드패드에서 cron.tab 파일 열기

Cron.tab 파일을 열면 하기와 같은 내용이 들어 있는 것을 확인할 수 있다.

cron.tab 파일 내용

Cron 사용법

Cron Format은 매우 간단하다. 다음은 nnCron LITE Help에서 발췌한 내용이다(Cron이 설치된 폴더의 doc\help.chm을 참고).

Cron Format
Cron 예제

위에서 보듯 '분, 시간, 날짜, 월, 요일'을 설정해서 특정 프로그램을 실행할 수 있게 만드는 것이다.

위에서 워드패드로 열어본 Cron.tab 파일의 내용을 보면 이해가 쉽다.

#CRONTAB FILE 
# Classic crontab format:
# Minutes Hours Days Months WeekDays Command

#*/15 8-16 * * 1-5 checkmail.exe

위에 마지막 줄을 보면 '#'으로 해당 라인이 실행 되지 않도록 막혀 있다. 그 내용은 Cron Format과 Example을 참고로 해석을 해보면 다음과 같이 해석할 수 있다.

*/15 8-16 * * 1-5 checkmail.exe

매 15분 마다, 8시~16시 사이에만, 매일, 매월, 월~금요일에 checkmail.exe 파일을 실행하라는 것이다.

이와 같이 우리는 워드패드를 '관리자 권한으로 실행'하여 Cron.tab 파일에 특정 프로그램을 스케쥴링하여 실행 할 수 있다.

하기와 같이 0분, 9시, 매일, 매월, 월~금요일에 Python 파일을 실행하여 findgoodprice_naver.py를 컴파일하고 실행 하도록 셋팅을 하여 테스트를 해보았다. 

0 9 * * 1-5 python D:\03_Study\02_FastCampus\02_Python\04_work\findgoodprice_naver.py

내가 원한바와 같이 정확히 동작하는 것을 확인 할 수 있었다.

Excel 파일에 파이썬 크롤링으로 데이터를 저장한 후 다른 이름으로 저장을 할 필요가 생겼다.

하기 예와 같이 openpyxl로 다른 이름을 저장하는 것은 매우 간단했다.

from openpyxl import load_workbook

wb = load_workbook('D:/test1.xlsx')
wb.save('D:/test2.xlsx')
wb.close()

단지 저장할때 이름만 바꾸면 된다.

그런데 단순한 텍스트만 있는 엑셀파일에서는 크게 문제가 없지만, 여러가지 데이터가 복잡하게 삽입된 엑셀파일에서는 문제가 발생한다.

본인의 경우에는 다음과 같은 문제점이 발생했다.

당췌 무슨 소린지 모르겠다.

한참 고민을 하다가... 문득 한 가지 생각이 떠 올랐다.

그래서, 작은 발상의 전환을 해보았다.

먼저, 파일을 복사 하여 다른 이름으로 저장하고, 그 파일에 필요한 데이터를 openpxy를 이용해 넣는거다.

그렇게 간단한 방법이 있었다.. -_-;;

다음과 같이 코드를 입력하면 파일을 다른 이름으로 복사할 수 있다.

import os
import shutil
import datetime

shutil.copy('D:/test1.xlsx', 'D:/test1.xlsx')

역시... 쉬운 방법은 따로 있었다.

Selenium library는 웹 크롤링을 할때 필수적인 library이다.

특별히 send_keys()함수를 이용하여 키보드의 키를 PC에 전달 할 수 있는데, 이때 사용가능한 값들은 다음과 같다.

Kyes.ENTER, Keys.ARROW_DOWN, Keys.ARROW_LEFT, Keys.ARROW_RIGHT, Keys.ARROW_UP,
Keys.BACK_SPACE, Keys.CONTROL, Keys.ALT, Keys.DELETE, Keys.TAB, Keys.SPACE,
Keys.SHIFT, Keys.EQUALS, Keys.ESCAPE, Keys.HOME, Keys.INSERT, Keys.PAGE_UP,
Keys.PAGE_DOWN,Keys.F1, Keys.F2, Keys.F3, Keys.F4, Keys.F5, Keys.F6, Keys.F7,
Keys.F8, Keys.F9 Keys.F10, Keys.F11, Keys.F12

예를 들어 Enter key를 전달하고 싶다면, send_key(Keys.ENTER)라고 사용하면 된다.

Anaconda를 이용하여 Qt Designer를 Install 한 경우, 다음과 같은 경로에 Qt Designer 실행 파일이 존재한다.

C:\Anaconda3\Library\bin

이 경로를 따라 들어가면 dsigner.exe 파일을 찾을 수 있다.

designer.exe 파일을 클릭하여 실행하면 Qt Designer가 실행된다.

 

또 다른 방법으로는 cmd 창을 열고 designer.exe를 타이핑 후 엔터를 치면 Qt Designer가 실행된다.

키움증권의 OpenAPI+를 사용하려면 다음과 같은 진행 순서를 따라야 한다.

   1. COM 오브젝트 생성

      "KHOPENAPI.KHOpenAPICtrl.1"이라는 ProgID를 QAxWidget 클래스의 생성자로 전달 or setControl 메서드를 사용.

         Ex 1>

              self.setControl("KHOPENAPI.KHOpenAPICrl.1")

         Ex 2>

             self.kiwom = QAxWidget("KHOPENAPI.KHOpenAPICrl.1")

   2. 로그인 실시

      CommConnect API 함수를 dynamicCall 함수를 통해 호출

         self.dynamicCall("CommConnect()")

   3. 이벤트 루프 만들기

      PyQt를 이용해 프로그램 한 경우 이미 내부에 이벤트 루프가 있어 따로 이벤트 루프를 만들 필요가 없다.

      하지만, PyQt를 이용하지 않는 경우는 명시적으로 이벤트 루프를 만들어야 한다.

      다음의 경우 PyQt의 QEventLoop 클래스의 인스턴스를 생성한 후 exec_ 메서드를 호출해 이벤트 루프를 생성하는 

      예제이다.

         self.login_event_loop = QEventLoop()

         self.login_event_loop.exec_()

   4. 이벤트 처리를 위한 메서드 연결

      키움증권 서버로부터 발생한 이벤트(OnEventConnect API)와 이를 처리할 메서드(_event_connect)을 연결하기 위해 OnEventConnect API에서 connect 매서드를 호출.

            self.OnEventConnect.connect(self._event_connect)

   5. 이벤트 처리 매서드 수행

      키움증권 서버로 부터 발생한 이벤트에 대해 위의 4번에서 연결한 _event_connect 매서드가 실행이 된다.

      실행이 될때 희망하는 동작을 수행 후 마지막에 comm_connect 메서드 호출 시 생성됐던 이벤트 루프를 종료한다.

         def _event_connect(self):

            중략....

            self.login_event_loop.exit()

matplotlib.finance 모듈을 사용하기 위해 아래와 같이 import를 했더니, No module named라는 Error가 발생한다.



Google을 뒤져서 확인을 해보니, stackoverflow에 다음과 같이 친절하게 설명이 있군~ ㅎㅎ


What this warning tells you is that the finance module will be removed at some point.

At the moment you don't need to worry about this warning. It will only affect you, when you update to a yet to be released version 2.2 of matplotlib, in which case you'll need to change your imports.

If you already want to be compatible with future versions now, you can download the mpl_financemodule from https://github.com/matplotlib/mpl_finance .

After having downloaded the files, you may install in the usual way,

python setup.py install

Alternatively you may try installing through pip,

pip install https://github.com/matplotlib/mpl_finance/archive/master.zip

The reason for this is that the people at matplotlib want to keep their code clean and not maintain a specialized sidepackage like this in the main code. They probably also do not want to maintain the package and spend resources on it, which can be better used in the core developpment.


일단 난 두번째 언급된 pip를 통해 mpl_finance를 install 해야겠다. 그리고 나서 matplotlib.finace 대신에 matplotlib.mpl_finance를 사용해야 한다는 것 ~!!!


먼저 pip install 실행을 위해 윈도우 시작 메뉴에서 Anaconda Proompt (py35)를 실행.



그리고 나서 Prompt 창에 위에 언급된 Pip install 명령어를 아래 그림의 빨간 줄처럼 실시하면, 알아서 쭈~욱 install 과정을 실시한다.



그럼 제대로 동작하는지 확인 하기 위해 아래와 같이 python을 실행해서 import 만 하면...



Error가 발생하지 않는다.

여기까지가 끝...


참고로, PyCharm에서 사용하려면, File --> Setting 을 선택한다.



그리고, Project Interpreter를 선택한 다음, 오른쪽 + 버튼을 누른다.



검색창에 mpl-finance라고 타이핑을 한 후 mpl-finance가 표시되면 선택하고, Install-package를 누르면 된다.



인스톨이 완료가 되었으면, PyCharm 콘솔창으로 가서 하기와 같이 import mpl_finance 명령어를 입력하고 enter를 쳤을때 Error가 발생하지 않으면 성공이다.



- End

Zipline 모듈 설치 작업 1 ~ 3까지 잘따라 왔다면, Python에서 Zipline을 잘 사용할 수 있다. 하지만 PyCharm에서는 어떻게 사용을 할 수 있을까???


간단하게 작업을 하나 실행하면 된다. 다음처럼 말이다.


1. Pycharm에서 File-->Setting을 선택한다.



2. Settting 창에서 "Project Interpreter"를 선택하면, 오른쪽 상단 빨간 네모 상자와 같이 현재 Pycharm에서 사용하고 있는 버젼의 Python이 표기 되어 있을 것이다. 본인것을 확인 해 보니 Python 3.7이다. 바로 이것을 "Zipline 모듈 설치 작업 - 1. 파이썬 3.5 버젼 설치" 시간에 설치한 Python 3.5로 변경하면 끝이나는 것인데...



3. 그러기 위해서 빨간 네모 박스의 톱니바퀴를 클릭한다.



4. 그러면 Add 와 Show All을 선택할 수 있는데, 여기서 Add를 누르면 된다.



5. Virtualenv Environment에서 Base Interpreter 부분의 오른쪽 끝, 즉 빨간 네모 부분을 선택한다.



6. 그러면 Select Python Interpreter 창이 뜨는데, 하기 빨간 네모 부분과 같이, Python 3.5를 인스톨한 경로에서 Python.exe를 클릭하면 된다.



7. 그 다음 OK를 누르고



8. 하기 빨간 네모 부분을 클릭하여 Python 3.5로 설정하면 모든게 끝이다. 그 다음 OK를 반드시 눌러져야 한다.



이제 Pycharm에서도 Zipline을 정상적으로 사용할 수 있다.


간단히 테스트로 import zipline을 타이핑 후 컴파일 하고 나서 Error가 없다면 정상적으로 설치 되었다는 의미.


- End

+ Recent posts