본문 바로가기
대동단결 Python

R에서 만든 보고서를 티스토리에 자동으로 올리는 Python

by 즐거운 지니 2020. 12. 26.
반응형

매일 매일 발생하는 데이터를 스크립트 R로 처리하고 R markdown 으로 보고서를 만든다. 그 결과물을 자동으로 티스토리 블로그에 올릴 수 있도록 할 수 있다.

자동으로 생성되는 보고서

R에서 만든 보고서를 티스토리에 자동으로 올리는 Python

이 블로그에는 매일 __돈키움픽__이라는 게시글이 올라온다. 돈키움픽은 매일 키움서버로 부터 주가데이터를 받아서 이를 처리하고 지수대비 상승한 종목을 우선순위로 보여준다. 이 과정에서 스크립트 언어인 R이 데이터를 처리하고, 키움에서 데이터를 수집하고, R에서 처리된 결과물을 블로그에 포스팅하는 것은 Python이 한다.
이 글에서는 R에서 처리된 자료를 티스토리에 자동으로 올리는 과정을 기술하고자 한다.

R 스크립트 실행하기

import os

os.system('"c:/Program Files/R/R-3.6.1/bin/Rscript.exe" D:/works/GenieDonKiwoom/jinfoPrintListRun.r')

python에서 R스크립트를 실행하는 것은 os모듈을 이용하여 위와 같이 매우 쉽게 실현된다. os.system은 외부 실행파일을 실행하는 함수로 실행 스크립트를 스트링형식으로 입력하면 하면 된다.

R에서 보고서 만들기 및 후작업

파이썬에서 실행된 R 스크립트 jinfoPrintListRun.r는 다음과 같다.

Sys.getenv()
library(rmarkdown)
render('jinfoPrintList.Rmd')

#install.packages('rvest')
library(rvest)
htmlcode <- read_html('jinfoPrintList.html', encoding = 'UTF-8')
htmlcode <- htmlcode %>% html_node('div')
htmlcode
write_html(htmlcode,'jinfoPrintListExtracted.html')

보고서를 만드는 작업은 jinfoPrintList.Rmd 에서 이루어진다. Rmd는 마크다운 스크립트인데 R스트립트를 실행하고 그 결과를 마크다운 스크립트로 변환하는 과정이 포함되어 있다. render('jinfoPrintList.Rmd') 는 Rmd파일을 실행한다. 그 결과로 jinfoPrintList.html파일이 생성된다.
그런데 우리는 티스토리에 생성파일을 첨부하는 것이 아니라. 그 내용을 포스팅하는 것이므로 헤더는 빼고 내용만 분리하는 과정이 필요하다. rvest는 html을 파싱하는데 유용한 R 모듈이다. 이를 이용하여 특정 dvi 내부만 추출하여 별도의 파일명 jinfoPrintListExtracted.html로 저장한다.

티스토리에 포스팅하기

티스토리에 포스팅하는 과정은 티스토리에서 제공하는 OpenAPI를 이용하여 Python에서 실행할 수 있다. 그 스크립트는 다음과 같다.

# coding=utf-8
import requests
import webbrowser
from datetime import datetime
import os

# client_id  == app_id
client_id = "904103ba87849e5141800a087"
# client_secret = Secret_Key
Secret_Key = "90417ba87849e511800a087168f312d96fdee5f67917ac049fc60cbc1d2e4b3"
# code 는 access_token 을 받기 위한 중간 인증코드, 한시간 내 한번만 사용됨.
code = "8a2c4469c37296cf6b5d6eb7cad78d4bb984346f8beb524f416bcae5601cef2e5fdbe4f0"
# access_token 최종인증키 유효기간동안 사용가능
access_token = "95d838152c7a891c9a81922_f7b4ffb34293e385c0b2cd"

# 티스토리 주소의 아이디나 전체주소
blog_name = "joyfulgenie.tistory.com"

# 콜백주소는 자신의 티스토리 주소를 사용해도 되고, 끝에 /는 넣지 않는다.
redirect_uri = "http://joyfulgenie.tistory.com"
state_param = "bm" #임의의 문자열
output_type = "json"

requests_headers = { #없어도 동작됨
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
}

# 먼저 코드를 생성하고,
if not code:
    auth_url = f'https://www.tistory.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&state={state_param}'
    webbrowser.open(auth_url)
    print('주소창에서 코드 값을 복사하세요. ?code= 이하')
    #r = requests.get(auth_url)
    #print(r.text)

# 이후에 액세스 토큰을 받아야 한다. 이게 좀 귀찮고 낮설다.
if code and (not access_token):
    print('acess token 시도중...')
    token_url = f'https://www.tistory.com/oauth/access_token?client_id={client_id}&client_secret={Secret_Key}&redirect_uri={redirect_uri}&code={code}&grant_type=authorization_code'
    #webbrowser.open(token_url)
    r = requests.get(token_url)
    print(r.text)

#    token_url = f'https://www.tistory.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=token'
#    webbrowser.open(token_url)



# 이제 실제 사용할 액세스 코드를 가지고 호출을 할 수 있다.

def get_info():
    info_url = f'https://www.tistory.com/apis/blog/info?access_token={access_token}&output={output_type}'
    r = requests.get(info_url, headers=requests_headers)
    return r.text


def get_list(page_number):
    url = f'https://www.tistory.com/apis/post/list?access_token={access_token}&output={output_type}&blogName={blog_name}&page={page_number}'
    r = requests.get(url, headers=requests_headers)
    return r.text


def get_category():
    url = f'https://www.tistory.com/apis/category/list?access_token={access_token}&output={output_type}&blogName={blog_name}'
    r = requests.get(url, headers=requests_headers)
    r = r.json()['tistory']['item']['categories']
    for i in r:
        print(f'{i["name"]} ({i["id"]})')
    return r


def get_write():
    now = datetime.now()  # current date and time
    today = now.strftime("%Y%m%d")
    title = '돈키움픽-' + today
    with open("jinfoPrintListExtracted.html", "r", encoding='UTF-8') as file:
        content = file.read()
    visibility = "3"  # 발행상태 0비공개-기본, 1보고,3발행
    category_id = "929746"  # 카테고리 아이디 기본값 0, 돈키움픽
    slogan = title  # 문자주소
    tag = "돈키움픽, 동키, 코스닥, 주식, 종목"  # 태그 ,로 구분
    acceptComment = ""  # 댓글 허용 (0, 1 - 기본값)
    password = ""  # 보호글 비밀번호
    url = 'https://www.tistory.com/apis/post/write'
    data = {'access_token': access_token, 'output': 'json', 'blogName': blog_name, 'title': title, 'content': content,
            'visibility': visibility, 'category': category_id, 'slogan': slogan, 'tag': tag,
            'acceptComment': acceptComment, 'password': password}
    r = requests.post(url, data=data)
    print(r, r.text)


# https://iamaman.tistory.com/2084
def file_upload():
    files = {'uploadedfile': open(filepath, 'rb')}
    params = {'access_token': token, 'blogName': blogName, 'targetUrl': blogName, 'output': 'json'}
    rd = requests.post('https://www.tistory.com/apis/post/attach', params=params, files=files)

    try:
        item = json.loads(rd.text)
        print(json.dumps(item, indent=4))
        print("----------------------------------------------")
        print(item["tistory"]["replacer"])
        print(item["tistory"]["url"])
        print(item["tistory"]["status"])
    except:
        print("Failed")


# R script 실행
os.chdir('D:/works/GenieDonKiwoom')
print(os.getcwd())
os.system('"c:/Program Files/R/R-3.6.1/bin/Rscript.exe" D:/works/GenieDonKiwoom/jinfoPrintListRun.r')
print(get_info())
get_category()
get_write()

 

반응형

댓글