[python] selenium 클릭 문제

selenium을 이용하던 중, 버튼을 클릭하는 곳에서 문제가 발생하였다.

분명 input이고 type은 button 인데 클릭을 하려고 하면 오류가 발생해서 고민과 검색을 통해서 아래와 같이 해결하였다. 처음 코드는 아래와 같았다.

driver.find_element_by_xpath("//input[@type='button']").click()

해당 코드를 사용해본 결과 정상 동작하지 않는 것을 확인, 구글 검색을 통해 Enter 키를 전송하면 클릭이 된다는 이야기가 있어서 아래와 같이 수정하여 적용해보았다.

driver.find_element_by_xpath("//input[@type='button']").send_key(Keys.ENTER)

하지만 위의 코드 역시 적용되지 않았기에 고민을 거듭하다가 html 코드를 자세히 보니 해당 버튼을 클릭하면 javascript를 호출하도록 되어 있었다.

<input type="button" value="button" onclick="some_java_script(some_value);">

그래서 그냥 selenium 자체에서 해당 스크립트를 실행하는 방법으로 변경하여 접근하였다.

driver.execute("some_java_script(some_value);")

해당 코드를 실행해 본 결과 정상적으로 동작하는 것을 확인하였다.

자동차 모니터링을 위한 TorquePro 로그 서버 구축

자동차를 관리하다보면 궁금한 것이 자꾸 생긴다. 예를들어 내가 이번 년도에 몇 키로나 운행했지? 내가 낸 최고 속도는? 자동차의 오일 변화는? 내가 자주 운행하는 곳은?

이러한 궁금증이 쌓이다보니 이전부터 안드로이드나 OBD2를 가지고 차량 상태를 모니터링 하는 방법을 고심하기도 했었다.

아무튼 현재 상태는 넥서스7 2세대 WiFi + OBD2 + TorquePro(App) + Advanced PID for Hyundai(App)의 조합으로 현 상태를 모니터링 할 수 있게 되었다. 넥서스7 2세대의 경우 일부 개조를 통해 자동차 시동이 걸리면 자동 부팅되고, 후방 카메라와 연결되어 화면을 출력해주는 등 여러가지 기능을 수행한다. 뭐, 이건 다음에 시간이 되면 따로 다루도록 하겠다.

이 구조에서 현재 상태 모니터링은 아무 문제 없었다. 현재 제네시스 쿠페 380에서 가장 큰 문제는 냉각 문제였는데… TorquePro를 사용하면 왠만한 정보는 다 읽을 수 있고, 심지어 오류코드 삭제까지 되니 충분했다. 하지만… 로그를 남길 수가 없었다.

물론 인터넷에 연결되었을 때 메일로 로그를 자동으로 보낼 수 있게하는 기능이 있긴하지만… 메일로 받아서 그걸 정리하고 데이터 추출하고… 귀찮은 일이 너무 많아지게 된다. 그래서 옵션을 좀 뒤지다보니… WebServerURL을 입력하는 곳이 있다! 그래서 조금 더 구글을 열심히 뒤져보니 TorquePro에서 인터넷이 연결되어 있을 경우, 주기적으로(최소 1초 단위) 모니터링하고자 하는 값들을 웹서버로 보내는 기능이 들어 있었다.

실제로 해당 기능을 바탕으로 TorquePro 공식 홈페이지에서 로그를 저장하고 볼 수 있는 기능을 제공하고 있고, 심지어 개인 서버에서 돌릴 수 있도록 PHP 등으로 구현된 서버 프로그램도 있었다.

그런데… 그래도 역시… 삽질은 해야 재미아니겠는가? 그래서 해당 내용들을 조사하고 정리하여 아래와 같은 구조로 동작한다는 것을 확인했다.

위의 그림을 보면 1단계는 TorquePro 어플리케이션에서 사용자가 설정한 URL로 GET 방식으로 Request 하는 것으로 시작한다. 가끔 인터넷 서핑할 때 http://……./…..?some=thing&all=about 같은 형태를 본적이 있을텐데 이게 GET 방식으로 데이터를 전달 하는 것이다.

해당 데이터를 JSON 형태로 보면

{
        "eml" : [EMAIL Address],
        "time" : [UNIX TIMESTAMP],
        "kff1001" : ....,
        .
        .
        .
        [KEY] : [VALUE]
}

위의 형태로 표현할 수 있다. 이게 GET 방식으로 전달되면

http://[URL]?eml=[EMAIL Address]&time=[UNIX TIMESTAMP]&kff1001=.....&[KEY]=[VALUE]

와 같이 데이터 전달을 수행한다. 일단 그럼 데이터는 서버로 전달된다. 그럼 서버에서는 해당 데이터를 파싱하고 저장하면 된다. 몰론 이걸로 끝은 아니다. 서버에서는 해당 데이터를 잘 받았다고 “OK!” 문자열을 응답으로 보내면 된다.

현재 해당 내용을 바탕으로 Flask + Apache2 를 이용하여 서버를 구축해보았다. 실제 데이터베이스에 저장된 내용은 아래와 같았다.

6320|[email]|1551670913242|kff1007|96.9
6321|[email]|1551670913242|GPSLongitude|000.000000
6322|[email]|1551670913242|kff1001|4.5
6323|[email]|1551670913242|GPSAccuracy|10.0
6324|[email]|1551670913242|GPSSatellites|8.0
6325|[email]|1551670913242|EngineRPM|635.0
6326|[email]|1551670913242|GPSAltitude|00.000000
6327|[email]|1551670913242|GPSLatitude|00.000000
6328|[email]|1551670913242|k-2149|56.0
6329|[email]|1551670913242|Bank1CatalystTemp|680.0
6330|[email]|1551670913242|TransmissionTemp|86.0
6331|[email]|1551670913242|v|8.0

실제 저장된 데이터를 보면 정상적으로 데이터가 들어오는 것을 알 수 있다. 아, GPS 정보도 정확하게 들어온다. 0으로 매워둔 것은 아무래도 개인 정보다 보니 가렸다. 아무튼, 지금 저장된 데이터의 이름은 KEY 값을 사람이 알아볼 수 있는 값으로 저장한 것이다. 현재까지 사용한 KEY 값은 다음과 같다.

k3c = "Bank1CatalystTemp"
k3d = "Bank2CatalystTemp"
k2f = "FuelLevel"
kff1001 = "GPSSpeed"
kff1006 = "GPSLatitude"
kff1005 = "GPSLongitude"
kff1007 = "GPSBearing"
kff1010 = "GPSAltitude"
kff123a = "GPSSatellites"
kff1239 = "GPSAccuracy"
kc = "EngineRPM"
k5 = "EngineCoolantTemp"
kfe1805 = "TransmissionTemp"
kf = "IntakeAirTemp"

일부값은 코드가 노출이 안되는 것들이 있었다. 특히 Advanced PID for Hyundai 같은 유료 PID 어플 같은 경우에는 PID가 나타나지 않아 조금 더 모니터링이 필요할 것으로 보여진다.

이번 작업은 대략적으로 어떻게 데이터를 받아들일지에 대한 고민을 해보고 해결을 하기 위해 작업한 것으로 정리할 곳이 많다. 그래서 코드나 웹을 공개하긴 조…금… 부끄럽다. 뭐, 계속해서 업데이트 해서 최종판을 공개하는게 목표긴하지만… 허허허 앞으로 지속적인 업데이트를 수행할 예정이다.

Apache2 + Flask 환경 구성

Apache2 에서 wsgi 모듈을 이용하여 Flask 개발 환경을 구성하는 방법에 대해 간단히 기록한다.

일단, Apache2에서 wsgi 모듈을 설치해야 한다.

sudo apt-get install libapache2-mod-wsgi

그 후에 간단한 구조를 구성해준다. 나는 그냥 간단하게 /FLASK/flask_app 폴더에 __init__.py와 flask_app.wsgi 파일을 생성해두었다.

/FLASK/flask_app/
                /__init__.py
                /flask_app.wsgi

먼저 __init__.py 에 Flask를 이용한 화면 뷰를 구성해준다.

import flask

app = flask.Flask(__name__)

@app.route("/")
def ok_print():
    return "OK!"

if __name__ == '__main__':
    app.run()

간단하게 접속하면 “OK!”를 뿌려주는 뷰이다. 다음으로 flask_app.wsgi 파일을 생성해준다.

#!/usr/bin/python
import sys
sys.path.insert(0, "/FLASK/")
from flask_app import app as application

간단히 보면 현재 패스를 /FLASK로 변경하고 flask_app의 app을 application으로 할당하여 apache2 mod_wsgi 모듈을 통해 실행한다는 의미로 이해된다. 그리고 /FLASK 폴더의 권한을 www-data:www-data로 할당한다.

chown -R www-data:www-data /FLASK

마지막으로 VirtualHost 세팅을 아래을 위해 /etc/apache2/sites-available 폴더에 파일을 하나 생성한다. 나는 편리한 사용을 위해 ok.teshi.net.conf 라는 파일명으로 생성해주었다. 해당 파일 내용은 아래와 같다.

<VirtualHost *:80>
        ServerAdmin [Mail Address]
        ServerName ok.teshi.net
        ErrorLog ${APACHE_LOG_DIR}/ok/error.log
        CustomLog ${APACHE_LOG_DIR}/ok/access.log combined

        WSGIDaemonProcess flask_app user=www-data group=www-data threads=5
        WSGIProcessGroup flask_app
        WSGIScriptAlias / /FLASK/flask_app/flask_app.wsgi
        <Directory /FLASK/flask_app>
            Order deny,allow
            Allow from all
            Require all granted
        </Directory>
        <Files /FLASK/flask_app/flask_app.wsgi>
            Order deny,allow
            Allow from all
            Require all granted
        </Files>
</VirtualHost>

위의 파일을 생성한 후,

sudo a2ensite ok.teshi.net

명령어를 사용하여 사이트를 VirtualHost에 추가한다. 그 후 Apache를 다시 불러온다.

sudo systemctl reload apache2

위와 같이 실행한 후 웹페이지를 열어 접속해본다.

[python] 웹 파싱, re 모듈 사용시 주의 사항

최근 웹 크롤링하는 프로그램을 취미삼아 짜고 있는데 특정 단어가 너무 거슬려서 제거 하기 위해서 re 라이브러리를 사용하고 있다.

사실 테스트 삼아 실행한 문자열은 잘 분리해주는데…

실제 적용하면 분리를 못해주는 증상이 있어서 한참보았더니… 유니코드 문제… 하아….

분리를 하려는 대상은 유니코드이고 검색하려는 값이 유니코드가 아니라서 발생한 문제 하아…

filter 값을 유니코드로 주면 해결된다. 혹시 몰라 기록.

[Synology] DS718+, gitlab 설치기

 GitHub 개발자 요금으로 사용한지 대략 2년 정도 된 상황에서 매달 결제가 되는것이 부담되기도 하고… 딱히 많이 쓰지는 않지만 잡다한 Repository를 구성하기가 애매해서 큰 마음을 먹고 Synology를 활용하기로 결정했다.

 Synology 에서 설치하는 방법 자체는 굉장히 쉬웠다. Synology 웹 접속을 통해서 패키지 센터를 켠 다음 “gitlab” 설치를 누르면 끝나는 일이었다. 설치 시간은? 제법 소요된다. 5분 정도 들여보다가 포기했었다.

설치됨은 무시하도록 하자 ㅇㅅㅇ

 버젼 자체는 GitLab CE 버젼으로 보였고 설치를 하게되면 기본적으로 Docker가 설치되고 Docker 컨테이너가 추가되게 된다. 설치되는 컨테이너는 gitlab, postsql, redis 로 3가지 조합으로 gitlab은 동작하게 된다.

설치 과정은?… 캡쳐하는 것을 잊었다… 이전버전에서는 다양한 값을 입력해줘야 했지만 최신 버전에서는 사용할 포트번호만 입력하면 되므로… 딱히 어려울 것이 없어서 생략한다.

메모리 사용량을 자세히 들여다 보자

 설치 과정은 별 것 없다고 이야기 했지만 위의 이미지 캡션에서도 보다시피 메모리 사용량을 자세히 들여다 보자. 현재 딱히 다른 작업을 수행하고 있지 않음에도 2.55 기가를 사용하고 있다. 물론 캐쉬된 것도 있긴하지만…

 가장 설치에서 짜증났던 점은바로 메모리였다. DS718+의 경우 최소 메모리 용량이 2기가이다. 딱히 업무용으로 사용할 것도 아니었기 때문에 ‘2기가 정도면 뭐 넉넉하게 쓰겠지?’ 라고 생각했던게 실수였다. 즉시 4기가 메모리를 사서 연결해주었다.

 물론 2기가에서도 설치는 가능했다. 설치시 걸리는 시간이 체감으로 2배 정도 더 걸렸고 설치 후 페이지 접속시 계속 타임아웃이 나는 건 어쩔 수 없었지만… 실제로 Raspberry Pi2 에 설치를 사용하신 분의 글도 읽어봤는데… 도저히 사용 못할 상테기 때문에 메모리 업그레이드를 추천한다.

“라즈베리파이에선 Gitlab이 돌아가긴 하지만 버겁다”  읽기

 Synology에서 gitlab을 설치하는데 중요한 점은 딱 한가지다.

메모리는 넉넉하게 쓰자.

다다익 메모리

 추가로 오래된 컴퓨터에 gitlab을 설치해서 운영하실 분들을 위한 최소 사양 가이드를 남겨둔다.

Requirements
 
 위의 링크에서 최소 사양을 확인할 수 있다. 단, 최소는 최소일 뿐이다. 2Core, 4GB는 기본으로 생각하는 것이 좋을것이다.

[Torque Pro] Torque Pro 스킨 개발 일지 -1-

Torque Pro 라는 어플의 스킨을 개발하기 위한 준비 과정을 적어본다.

 

1차로 전체 배경화면 사이즈, 넥서스7 2세대 WiFi 기준으로 1920 * 1200 이었다.

실제 캡쳐 후 측정 과정을 거쳐야겠지만 우선은 해당 값을 기준으로 고민해야 할듯하다.

 

스킨 개발을 위해서 Theme 제작법을 찾아보니 Property 파일을 사용해야한다.

자세한 내용은 https://torque-bhp.com/wiki/Themes 을 참조하였다.

 

우선 위의 두 가지 정보로 시작을 할 예정이며, 시뮬레이터가 있는지는 검색을 해보아야 할듯하다.

 

 

[tinkercad] Circuit 그려보기

자동차에 넥서스 7 2013년형을 심는 작업을 한참하던 중에 여러가지 문제가 생겨서 고민을 하다가 릴레이를 써서 컨트롤 하기로 결정을 내렸다. 하지만… 전기라는게 원래 무서운 것이라… 어떻게 할까 하다가 인터넷을 검색해보니 tinkercad를 이용해서 시뮬레이션 할 수 있다는 것을 찾았다.

 

TINKER CAD

 

위의 링크를 이용해서 들어갈 수 있다. 아무튼… 가장 큰 걱정거리는 릴레이를 어떻게 연결할지 그리고 두 개의 파워 소스를 어떻게 연결해야 안전한가에 대한 고민이 있었는데 재밌게 풀어낼 수 있었다.

TINKER CAD에 들어가서 Circuit을 선택하면 바로 그릴 수 있었다. 기본적으로 다양한 모듈을 지원해서 편리한 편이었고… 뭐, 나름 좋은 툴이었다.

거기다가 시뮬레이션 도중에 파워를 끈다던가 전압을 변경하는 것 같은 값을 변경할 수 있는 것들이 있어서 편리했다.

 

아래는 간단하게 그려본 병렬 회로에 릴레이를 연결한 것이다. 릴레이에 전기를 흘리지 않으면 전기가 흐르지 않는다.

아래는 맨 아래쪽 전기 소스의 전원을 켠 상태이다. 릴레이에 전기가 흐르고 5A의 전압이 합쳐져 10A 전압이 발생한 것을 알 수 있다.

자, 그러면 릴레이에 전압을 오버해서 넣어보다.

요렇게 릴레이가 펑하고 터져버린다. 나름 괜찮은 도구인듯 하여 기록하여 둔다.

 

[Synology] SMS 메세지를 위한 세팅

경고가 발생했을 때, 기본적으로 메세지를 보낼 수 있도록 Synology를 세팅할 수 있으나… 문자를 제공하는 방법을 몰라서 일단 미루어 두었다가 작업을 수행하였다.

 

먼저 해당 작업을 수행하기 위해서는 Synology 화면에 접속하여 제어판 -> 알림으로 간 후 상당 메뉴에서 SMS를 선택한다. 기본적으로 설정되어 있는 것은 clicktell로 되어 있는데 이를 사용할 수는 없을 것 같았다. 일단 외국에 있는 업체니…

아무튼 이곳에 한국에서 SMS를 제공하는 업체를 찾아야했다. 가장 중요한것은 HTTP 기반의 API를 제공하는지가 중요하다. HTTP 기반의 API를 지원한다면 아래와 같은 URL로 접속시 SMS가 전송이 된다.

http://some.sms_service.com/http/api/send?user=teshi&password=teshi_password&to=01022224444&text=메세지전송 테스트

위의 URL은 크게 ? 앞과 ? 뒤로 나눌 수가 있다. ? 앞은 메세지를 보내는 URL, ? 뒤의 값은 메세지를 보내는 옵션값이라고 생각하면 이해하기 좋을 것이다. 앞에 주소는 서비스 업체에서 제공하니 뒤의 옵션 값만 살펴보자. 뒤의 옵션값은 여러개의 값으로 구분되어 있고 &로 나누어서 볼 수 있다.

user=teshi

password=teshi_password

to=01022224444

text=메세지전송 테스트

이렇게 세로로 풀어보면 조금더 쉽게 보인다. 사용자가 teshi이고 패스워드가 teshi_password인 사용자가 01022224444에가 ‘메세지전송 테스트’ 라는 텍스트를 보내라는 의미가 된다.

한국에서 HTTP를 사용해서 메시지를 전송할 수 있는 업체를 검색하다보니… COOL SMS 라는 곳을 찾을 수 있었다.

 

COOL SMS 홈

COOL SMS HTTP API

 

회원가입 절차는 대략 다음과 같았다

  1. 회원가입
  2. API 등록
  3. 발신번호 등록
  4. 충전

위의 절차는 홈페이지나, API 설명에 자세하게 나와 있으니 따로 설명하지 않고 다음으로 넘어간다.

 

자 그럼 서비스 제공 업체를 추가해보자.

제어판 -> 알림 으로 들어가서 상단 탭에서 SMS를 선택한다. 선택한 후 중간 쯤을 보면 “SMS 서비스 제공업체 추가”라는 버튼이 있다. 이 버튼을 누르고 창이 뜬다.

입력하는 부분은 두 부분이다. 공급자 이름, SMS URL 그 중에서 공급자 이름은 아무렇게 입력해준다. 그리고 SMS URL은 아래와 같이 입력해준다.

공급자 이름 : CoolSMSTEST

공급자 이름은 저렇게 쓰고 아래에 URL은 다음과 같이 써준다.

https://api.coolsms.co.kr/sendmsg?user=[ COOL SMS ID ]&password=[ COOL SMS PASS ]&to=[ 받을 전화 번호 ]&from=[ 보낼 전화 번호 ]&text=[ 보낼 내용 ]

[ 와 ] 사이에 있는 글자는 자신의 정보로 변경하면 된다. 그러면 아래와 같이 될 것이다.

개인정보 때문에 다 지웠더니 이상한 모습이지만 저런식으로 될 것이다. 그러면 다음을 누른다.

위의 창이 나오면 각 매개변수를 설정해줘야 한다. 처음에는 다 “기타”로 설정되어 있으므로 각 값에 알맞게 선택해준다. user로 시작하는건 사용자 이름, password로 시작하는건 패스워드 등을 각각 설정해준다. 그 후 적용을 누른다.

그러면 위와 같이 적용될 것이다. 이제 정보를 다시 입력해주자. 사용자 이름, 패스워드, 기본 전화 번호 까지만 적고 테스트 SMS 메시지 전송을 누른다.

전화번호 입력 유의 사항

이때 주의 사항! 010 앞에 +82 같은 건 넣어주면 동작하지 않는다.

그냥 빈칸으로 두고 앞 칸에 010을 적고 뒤에 나머지를 적어주자.

마지막으로 테스트 SMS 메시지 전송을 통해 메시지 확인만 된다면.. 끝!

꼭, Cool SMS 를 써야 하는 건 아니지만 일단 검색 결과 Cool SMS가 API를 잘 설명해두어서 해당 서비스를 사용하기로 했다. 더 저렴한 곳이나 더 편리한 곳이 있다면 거길 써야겠지만… 한 동안은 이렇게 사용할 것 같다.

나중에 세팅할 때 도움이 되고자 기록해둔다.

 

 

[Synology] Synology에 입문하다.

이전에는 개인 서버, 컴퓨터 혹은 라즈베리 파이를 이용하여 NAS를 구성해서 썼다.

전문적인 기능이 필요하지도 않았고, 사실 개발 머신 역활도 하던 녀석이기 때문에 불편함을 느끼지 않았다.

 

이번에는 조금 다른 상황이 왔다. 무려 4테라에 육박하는 데이터를 받을 일이 생기게 되었다.

기존 서버? 신뢰하지 못할 수준은 아니나 레이드가 걸려있었던 것도 아니고 그냥 USB 외장 하드 하나 연결되어 있던 곳이라 신뢰도는 더욱 떨어졌다. 그래서 큰 결심을 하게 되었다. 8테라 사이즈로 NAS를 구입하자.

 

인터넷을 조금만 검색해보니… 답이 나왔다. Synology 밖에 없다.

결국 2베이용을 구입해서 ( 나중에 확장은 확장 베이를 구매하면 되니 ) 8테라 하드 디스크 두개를 구입해서 NAS를 구입했다. 그리고 구입한 김에 여러가지 시행착오 혹은 삽질기를 적어보고자 카테고리도 만들었다.

 

 

PS,  NAS 구축을 위해 하드 디스크를 구하려 했으나 8테라는 잘 가져다 두지 않는데다가… 외장 하드랑 가격이 비슷해서… 그냥 외장하드 두개를 산뒤 디스크를 추출했다. 삽질이긴 하지만… 뭐…

블로그 서버 유지 관리 비용

어제 아시는 분이 블로그 서버를 유지하는데 사용되는 비용에 대하여 질문을 하여, 간단하게 정리해본다.

먼저 환경은

Vultr 가상화

DNSEver 도메인 포워딩

이 두가지를 메인으로 사용하고 있다.

 

사실 DNSEver를 사용하지 않아도 Vultr 내부의 고정 아이피를 사용하면 되지만, 아무래도 해당 도메인을 블로그 서버에만 연결시켜 둔 것은 아니기 때문에 DNSEver를 사용하는 것이 좋은 방법이 되었다.

 

우선 Vultr 에 들어가는 비용은

 

 

달에 16.00$ 가 들어간다. 10.00$ 인스턴스 하나와 고정 IP 6$ 하나를 이용해서 나온 금액이다.

물론 접속자가 많다면 조금 더 가격이 올라 갈 수 있다. 하지만 현재까지는 많은 사람이 오지는 않기 때문에 16$ 로 충분히 유지가 가능하다. 16$ 는 16,000원으로 생각하도록 하고…

 

다음은 DNSEver에 들어가는 비용이다. 이것 역시 여러가지 모델이 있으니 자기한테 적절한 것을 선택하는 것이 좋을 것 같다. 우선 나 같은 경우는 이렇다… 정도로 이해하면 좋을 것 같다.

 

 

DNSEver는 미리 포인트를 구입해두고 포인트 차감 방식으로 동작한다. 1포인트는 1원으로 많은 양을 충전할 수록 보너스 포인트를 조금 챙겨준다. 내가 사용하는 요금제의 경우 한달에 1,500원을 사용한다. 여기서 조금 더 많은 사람이 들어오는 달에는 최대 2,000원을 사용하는 것을 볼 수 있었다.

 

그렇다면 한 달에 들어가는 비용은 18,000원, 맥시멈으로 20,000원 정도 잡으면 1년에 240,000원의 비용이 소요된다는 의미이다.

240,000원이라… 사실 이 돈이면 라즈베리파이나 그 유사한 무언가를 사고 유지관리를 하는 것이 더 저렴하게 먹히는 것을 알 수 있다.

하지만 최근 잦은 이사와 이동으로 고민을 해보면… 편의성이나 내가 관리를 할 필요가 없다는 사실이 더욱 좋게 다가오기는 한다.