본문 바로가기

Dev/Python

Python과 티스토리 API를 활용하여 글을 작성하기 - 개선판

https://woongbinni.tistory.com/entry/Python%EA%B3%BC-%ED%8B%B0%EC%8A%A4%ED%86%A0%EB%A6%AC-API%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EA%B8%80%EC%9D%84-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0?category=861369

 

Python과 티스토리 API를 활용하여 글을 작성하기

일간으로 주식 분석 정보를 포스팅하려면 분석에서 포스팅의 과정중 어느정도는 자동화가 되어야 했다. (아니면 근성이 있던가.. ) 분석 결과를 마크다운 포멧의 리포트로 나오게 하였고 이를 포스팅하는 것은 내..

woongbinni.tistory.com

 일전에 포스팅을 한번 했었기는 했는데, 그때도 의아했던 것이 '분명히 POST 방식을 쓰고 있는데 글 작성 컨텐츠를 모두 URL에 때려넣고 있는가?' 였었다. 심지어 공식 티스토리 API 문서도 그렇게 예시를 보여주고 있다. 

https://tistory.github.io/document-tistory-apis/apis/v1/post/write.html

 

글 작성 · GitBook

No results matching ""

tistory.github.io

 별다른 생각없이 '그래야 하나보다.' 라고 생각했는데, 이렇게 모든 정보를 URL에 때려넣게 되면 보안문제도 있거니와, 더 심각한 문제점이 하나 있는데, 포스팅하는 컨텐츠의 길이 제약을 심하게 받는다. 주식 종목분석기의 자동 포스팅을 하면서 테스트해본 결과 5*15정도의 테이블 하나를 컨텐츠로 넣으면 그 이상은 길이제한이 걸려 글 등록이 안된다. 

 한참을 지나서야 전송할 데이터들을 request body에 넣어서 api를 쏴볼 생각을 하게 되는데.... 해보니까 된다. -_-;; 이래서 게으르면 안된다. (사실 이 내용도 한참전에 알았는데 포스팅을 이제야 한다.) 새로 개선된 코드는 아래와 같다. config의 경우는 따로 치환해야한다. python에서 config 코드는 아래 링크를 참고하면 된다.

https://woongbinni.tistory.com/entry/json%ED%8C%8C%EC%9D%BC%EB%A1%9C%EB%B6%80%ED%84%B0-%EC%84%A4%EC%A0%95%EA%B0%92%EC%9D%84-%EC%9D%BD%EC%96%B4%EB%93%A4%EC%9D%B4%EB%8A%94-python-code

 

json파일로부터 설정값을 읽어들이는 python code

https://woongbinni.tistory.com/entry/Python%EA%B3%BC-%ED%8B%B0%EC%8A%A4%ED%86%A0%EB%A6%AC-API%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EA%B8%80%EC%9D%84-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0-%E..

woongbinni.tistory.com

import requests
import re
import os
import markdown
from config.config import config

class PostingService:
  access_token = None

  def getAccessToken(self):
    oauth_url = "https://www.tistory.com/oauth/authorize"  # 인증 서버 접속용
    login_url = 'https://www.tistory.com/auth/login'  # 로그인 서버 접속용
    callback_url = config["TISTORY"]["COLLBACK_URL"]

    req_params = {
      'client_id': config["TISTORY"]["CLIENT_ID"],
      'redirect_uri': callback_url,
      'response_type': 'token'}

    login_info = {'loginId': config["TISTORY"]["LOGIN_ID"],
                  'password': config["TISTORY"]["PASSWORD"],
                  'redirectUri': callback_url}

    with requests.session() as s:
      response = s.post(login_url, data=login_info)

      if (response.status_code == 200):
        try:
          redirect = s.get(oauth_url, params=req_params)
        except requests.exceptions.ConnectionError as e:  # 내겐 리다이렉트할 콜백 URL이 없는 주소를 적었기에 에러가 발생한다.
          received = e.request.url
          p = re.compile("(?<=access_token=)\w+")
          m = p.search(received)
          access_token = m.group()
          self.access_token = access_token

  def createPost(self, title, content, category_name, tag):
    access_token = self.access_token
    blog_name = config["TISTORY"]["BLOG_NAME"]
    title = title  # 제목 (필수)
    content = content  # 글내용(필수)
    visibility = "0"  # 발행상태 0비공개-기본, 1보호, 3발행
    category_id = self.getCategoryId(category_name)  # 카테고리 아이디 기본값 0
    slogan = ""  # 문자주소
    tag = tag  # 태그 ,로 구분
    acceptComment = "1"  # 댓글 허용 (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.text)
    return r.text

  def getCategoryId(self, category_name):
    access_token = self.access_token
    blog_name = config["TISTORY"]["BLOG_NAME"]

    url = f'https://www.tistory.com/apis/category/list?access_token={access_token}&output=json&blogName={blog_name}'
    r = requests.get(url)
    categories = r.json()['tistory']['item']['categories']
    ret = None
    for category in categories:
      if category['name'] == category_name:
        ret = category['id']
        break

    return ret

if __name__ == '__main__': 
  self.getAccessToken() 
  title = '타이틀'
  content = '내용~ 긴내용도 이젠 괜찮아~~ '
  category_name = '티스토리 카테고리 이름~~ '
  tag = '태그,콤마로,구분됨'
  self.createPost(title, content, category_name, tag)