외부 프로그램을 실행하고 그 표준 출력/에러를 텍스트 컨트롤에 표시하는 어플의 Template입니다.


template2.py
# -*- coding: utf-8 -*-
#!/usr/bin/python
 
import wx
import subprocess
import threading
import sys
 
COMMAND_PATH = "test.py" # 실행할 외부 프로그램 경로

def stdout_thread(pipe, callback):
    for line in iter(pipe.stdout.readline, b''):
        callback(line.rstrip())

def exec_command(cmd, callback, cwd=None):
    p = subprocess.Popen(cmd, 
                         stdout=subprocess.PIPE, 
                         stderr=subprocess.STDOUT, cwd=cwd)
    out_thread = threading.Thread(name='stdout_thread', target=stdout_thread, args=(p, callback))

    out_thread.start()
 
class MainWindow(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size = (480, 320),
            style = wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
             
        vbox = wx.BoxSizer(wx.VERTICAL)

        self.tc = wx.TextCtrl(self, 1, size = (-1, 200), style = wx.TE_MULTILINE)
        vbox.Add(self.tc, 0, wx.EXPAND | wx.ALL)

        self.SetSizer(vbox, True)
        self.Layout()
         
def callback_stdout(msg):
    print("}}} " + msg)
    frame.tc.AppendText(msg + "\n")
             
app = wx.App(False)
frame = MainWindow(None, -1, u"Title")
frame.Show(1)

exec_command([sys.executable, COMMAND_PATH], callback_stdout)

app.MainLoop()


test.py
# -*- coding: utf-8 -*-
#!/usr/bin/python

import sys

print "blah;blah;"
sys.stdout.flush()


[주의사항] 실행하려는 외부 프로그램이 python 코드일 때, 외부 프로그램에서 메세지 출력 후 sys.stdout.flush()를 해줘야 메세지가 그때 그때 출력된다. 그렇지 않으면 메세지가 마지막에 한꺼번에 출력된다.


template2.py 실행 화면


 


<테스트 환경>
OS : Windows 7
Python 버전 : 2.7
wxPython 버전 : 2.8.12.1


,

파이썬에서 문자열은 바이트 코드와 유니코드로 나뉜다.


바이트 코드는 euc-kr, UTF–8 등과 같이 특정 인코딩이 적용된 문자열을 말한다. 파이썬에서 유니코드는 어떤 특정 인코딩에 속하지 않는 유니버셜한 어떤 것을 나타낸다. (다른 언어에서 흔히 UTF–8을 유니코드로 일컫는 것과는 다름에 유의)

  • 유니코드 >>> 바이트 코드로 변환하기 위해서는 encode() 함수가 사용된다.

  • 바이트 코드 >>> 유니코드로 변환하기 위해서는 decode() 함수가 사용된다.

    str = ustr.encode("UTF–8") # 유니코드에서 UTF–8 바이트 코드로 변환 ustr = str.decode("UTF–8") # UTF–8 바이트 코드에서 유니코드로 변환

  • type() 함수를 사용하여 어떤 문자열이 유니코드인지 바이트 코드인지 알아낼 수 있다.

    print type(str) # 바이트 코드일 경우
    -> <type 'str'>
    
    print type(ustr) # 유니코드일 경우
    -> <type 'unicode'>
    


소스 코드 상에서 대입시,


[1]

# -*- coding: utf-8 -*-

myStr = "가나다"

myStr의 타입 -> utf-8의 <type 'str'>

[2]

# -*- coding: cp949 -*-

myStr = "가나다"

myStr의 타입 -> cp949의 <type 'str'>

[3]

myStr = u"가나다"

myStr의 타입 -> <type 'unicode'>

'# -*- coding: ~' 을 붙이지 않을 경우, 시스템 로케일인 cp949의 <type 'str'>로 적용되어야 할 것 같은데, 실제 테스트 결과는 utf-8로 적용된다??


[참고] 이것은 파이썬 2.X 대에서 적용되는 내용이고, 파이썬 3.X 대에서는 방식이 약간 달라지게 되는데...


테스트 환경
- OS : Windows 7
- Python 버전 : 2.7


,

위의 두 글을 참고하면 웹페이지의 특정 class에 해당하는 부분을 추출하여 텔레그램 채널로 보내는 것이 가능하다. (두둥)


Python 2 :
# -*- coding: utf-8 -*-
  
import requests
from bs4 import BeautifulSoup
    
r = requests.get('http://httpbin.org')
   
# beautiful soup 초기화
soup = BeautifulSoup(r.text, "html.parser")
   
# class로 찾기
mr = soup.find(class_="bash")
result = mr.get_text()
result_utf8 = result.encode("UTF-8")
  
# 텔레그램 채널로 전송
url = "https://api.telegram.org/bot<텔레그램 봇 토큰>/sendMessage"
headers = {"Content-type": "application/json"}
params = '{"chat_id": "@<채널 ID>", "text": "텍스트 추출 : %s"}' % result_utf8
r = requests.post(url, headers = headers, data = params)
   
print(r.text)

Python 3 :
# -*- coding: utf-8 -*-
  
import requests
from bs4 import BeautifulSoup
    
r = requests.get('http://httpbin.org')
   
# beautiful soup 초기화
soup = BeautifulSoup(r.text, "html.parser")
   
# class로 찾기
mr = soup.find(class_="bash")
result = mr.get_text()

# 텔레그램 채널로 전송
url = "https://api.telegram.org/bot<텔레그램 봇 토큰>/sendMessage"
headers = {"Content-type": "application/json"}
params = '{"chat_id": "@<채널 ID>", "text": "텍스트 추출 : %s"}' % result
r = requests.post(url, headers = headers, data = params.encode("UTF-8"))
   
print(r.text)


테스트 환경
 - OS : Windows 7
 - Python 버전 : 2.7, 3.6


,

사전 설치 요구사항


Beautiful Soup 모듈 사용시, 추가적인 Beautiful Soup 모듈 설치를 필요로 한다.

pip install bs4


HTML 파싱 예제

# -*- coding: utf-8 -*-
 
from bs4 import BeautifulSoup
import requests
 
# request 모듈을 사용하여 웹 페이지의 내용을 가져온다
url = 'http://httpbin.org'
r = requests.get(url)
 
 
# beautiful soup 초기화
soup = BeautifulSoup(r.text, "html.parser")
 
# 태그로 찾기 (첫번째 항목)
mr = soup.find("a")
print mr.get_text() # get_text() 함수는 도큐먼트 혹은 특정 태그 밑에 있는 모든 텍스트를 추출한다
print mr.string
 
# 태그로 찾기 (모든 항목)
mr = soup.find_all("a")
print mr[0]
 
# id로 찾기
mr = soup.find(id="AUTHOR")
print mr.get_text()
 
# class로 찾기
mr = soup.find(class_="bash")
print mr.get_text()
mr = soup.find("code", class_="bash") # id와 class를 조합하여 찾을 수도 있다
print mr.get_text()
 
# 찾기 결과에 대해 다시 한번 찾기를 수행할 수 있다
tables = soup.find("ul")
mr = tables.find("li")
print mr


테스트 환경
 - OS : Windows 7
 - Python 버전 : 2.7


,

로그인 등에서 서버로부터 전달받은 쿠키를 유지해야하는 경우, requests 모듈을 사용하는 것이 낫다.


사전 설치 요구사항


requests 모듈 사용시, 추가적인 requests 모듈 설치를 필요로 한다.

pip install requests


기본 HTTP 요청

import requests
 
r = requests.get('http://httpbin.org/ip') 

print(r.text)
print(r.status_code)
 
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://httpbin.org/get', params=payload)
 
print(r.url)
print(r.text)
print(r.status_code)
  • https 접속을 위해서는 url 안에 직접 ’https://~’와 같은 형식으로 입력하면 된다.
  • 특정 포트 지정시는 아래와 같이 사용한다.
  • r = requests.get('http://httpbin.org:8080/ip') 
    


POST 요청

import requests

r = requests.post('http://httpbin.org/post', data = {'key':'value'})

print(r.text)
print(r.status_code)


헤더 추가

import requests
 
url = 'http://httpbin.org/get'
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get(url, headers=headers)


참고 사이트


<테스트 환경>
 - OS : Windows 7
 - Python 버전 : 2.7
,

파이썬을 사용하여 텔레그램 채널에 메세지를 보내는 예제입니다.
<텔레그램 봇 토큰>과 <채널 ID> 부분은 아래 글에서 설명했던 값으로 바꿔줍니다.


–> 텔레그램 봇으로 채널 포스팅 - 1. 준비 작업


Python 2 :
# -*- coding: utf-8 -*-

import requests
 
url = "https://api.telegram.org/bot<텔레그램 봇 토큰>/sendMessage"
headers = {"Content-type": "application/json"}
params = '{"chat_id": "@<채널 ID>", "text": "test string [한글]"}'
r = requests.post(url, headers = headers, data = params)
 
print(r.text)
print(r.status_code)

Python 3 :
# -*- coding: utf-8 -*-

import requests
 
url = "https://api.telegram.org/bot<텔레그램 봇 토큰>/sendMessage"
headers = {"Content-type": "application/json"}
params = '{"chat_id": "@<채널 ID>", "text": "test string [한글]"}'
r = requests.post(url, headers = headers, data = params.encode("UTF-8"))
 
print(r.text)
print(r.status_code)


참고 글


<테스트 환경>
 - OS : Windows 7
 - Python 버전 : 2.7, 3.6
,


기본 HTTP 요청하기

import httplib

conn = httplib.HTTPConnection("httpbin.org")

conn.request("GET", "/ip")
r1 = conn.getresponse()
print r1.status, r1.reason
data1 = r1.read()
print data1

conn.request("GET", "/get")
r2 = conn.getresponse()
print r2.status, r2.reason
data2 = r2.read()
print data2

conn.close()
  • https 접속을 하려면, httplib.HTTPConnection 대신에 httplib.HTTPSConnection을 사용한다.

> conn = httplib.HTTPSConnection("httpbin.org")

  • 특정 포트 지정시는 아래와 같은 방법 중 한가지를 사용한다.

> conn = httplib.HTTPConnection("httpbin.org:80")

> conn = httplib.HTTPConnection("httpbin.org", 80)


POST 요청하기

import httplib, urllib

conn = httplib.HTTPConnection("httpbin.org")

params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
headers = {"Content-type": "application/x-www-form-urlencoded",
           "Accept": "text/plain"}
conn.request("POST", "/post", params, headers)
response = conn.getresponse()
print response.status, response.reason
data = response.read()
print data

params = "test string"
headers = {"Content-type": "text/html"}
conn.request("POST", "/post", params, headers)
response = conn.getresponse()
print response.status, response.reason
data = response.read()
print data

conn.close()


참고 사이트

  • http://httpbin.org : 각종 HTTP 요청들에 대한 응답을 테스트할 수 있는 사이트


<테스트 환경>

 - OS : Windows 7
 - Python 버전 : 2.7


,


PIP는 파이썬으로 작성된 패키지 소프트웨어를 설치, 관리하는 패키지 관리 시스템이다. 파이썬 2.7.9 이후 버전과 파이썬 3.4 이후 버전은 pip를 기본적으로 포함한다.



사전 준비사항


1) 파이썬 2.7.9 혹은 3.4 이후 버전


기본적으로 pip가 포함되어 있지만, 파이썬 실행 파일과 경로가 다르기 때문에 <파이썬 설치 경로>/scripts를 PATH 환경 변수에 추가해야 한다.


2) 파이썬 2.7.9 혹은 3.4 이전 버전


아래 PIP 사이트에서 get-pip.py 파일을 받아 실행하면 설치할 수 있다. 설치 후 역시 PATH 환경 변수에 추가가 필요하다.


 - https://pip.pypa.io/en/stable/installing/


python get-pip.py





사용 방법


1) 패키지 설치


pip install some-package-name


2) 패키지 제거


pip uninstall some-package-name



,