[티스토리] Python Open API 활용 블로그 RSS 생성 소스
예전엔 티스토리에서 블로그 전체 백업기능이 있었는데 지금은 없어졌습니다.
RSS 기능으로 백업은 가능한데 최대 50개까지만 가능합니다.
그래서 파이썬으로 전체 게시글을 RSS 로 만들어 주는 프로그램을 만들어서 공개합니다.
RSS 만 있으면 워드프레스로 플러그인을 이용하면 블로그 이전이 가능합니다.
물론 이미지 파일은 티스토리가 존재해야 이미지가 보여집니다~
이미지까지 백업하지 않는 이상 완전한 탈출은 힘듭니다.
# yum install python python-pip
# pip install requests pytz
사전에 python 관련해서 미리 설치를 하여야 합니다.
▶ Python 소스코드
# coding=utf-8
import json
import math
import requests
import urlparse
import xml.etree.ElementTree as xml
from datetime import datetime
from pytz import timezone
headers = { ### 헤더 필요시 requests.post(URL, headers=headers)
'Referer':'https://www.tistory.com/auth/login',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'
}
URL_0 = 'https://www.tistory.com/auth/login' ### 티스토리 로그인 URL
URL_1 = 'https://www.tistory.com/oauth/authorize' ### 인증 요청 및 Authentication code 발급 URL
URL_2 = 'https://www.tistory.com/apis/blog/info' ### 블로그 정보 URL
URL_3 = 'https://www.tistory.com/apis/post/list' ### 블로그 리스트 URL
URL_4 = 'https://www.tistory.com/apis/post/read' ### 블로그 상세보기 URL
loginParams = { ### 로그인 Parameters ( 블로그주소, 이메일계정, 비밀번호 )
'redirectUrl':'http://ivps.tistory.com',
'loginId':'이메일계정',
'password':'비밀번호'
}
tokenParams = { ### 토큰값을 받아오기 위한 Parameters ( App ID, CallBack, 'token' )
'client_id':'Open API App ID',
'redirect_uri':'Open API CallBack',
'response_type':'token'
}
def params_2(access_token): ### 블로그 정보 Parameters
return {'access_token':access_token, 'output':'json'}
def params_3(access_token, blogName, page, count): ### 블로그 리스트 Parameters
return {'access_token':access_token, 'output':'xml', 'targetUrl':blogName, 'page':page, 'count':count}
def params_4(access_token, blogName, post_id): ### 블로그 상세보기 Parameters
return {'access_token':access_token, 'output':'xml', 'targetUrl':blogName, 'postId':post_id}
blogName = 'ivps' ### 블로그명
page = 0 ### 1 페이지 부터 시작
count = 30 ### 최대값 30
post_id = 0 ### 아래에서 데이터를 추출
access_token = '' ### 아래에서 데이터를 추출
rs = requests.session()
try:
r0 = rs.post(URL_0, data=loginParams)
try:
r1 = rs.get(URL_1, params=tokenParams)
access_token = str( urlparse.parse_qs( r1.url.split('#')[1] )['access_token'][0] )
print('### access_token : ' + access_token)
try:
r2 = rs.get(URL_2, params=params_2(access_token))
print('### Open API, Blog Info Url : ' + str(r2.url))
#print(r2.text)
item = json.loads(r2.text)
item_size = len(item['tistory']['item']['blogs'])
### RSS XML Create
rss = xml.Element('rss')
rss.set('version', '2.0')
x1_ch = xml.SubElement(rss, 'channel')
for i in range(item_size): ### 0 ~ 5, 없거나 최대 5개의 블로그
blog_name = item['tistory']['item']['blogs'][i]['name']
if(blog_name == blogName): # 일치하는 블로그만
print('### Find blog : ' + str(blog_name))
### ==> 필요는 없지만 티스토리 rss 에 나온는 형식에 맞춰줌
x1_ch_ti = xml.SubElement(x1_ch, 'title').text = item['tistory']['item']['blogs'][i]['title']
x1_ch_li = xml.SubElement(x1_ch, 'link').text = item['tistory']['item']['blogs'][i]['url']
x1_ch_de = xml.SubElement(x1_ch, 'description').text = item['tistory']['item']['blogs'][i]['description']
x1_ch_la = xml.SubElement(x1_ch, 'language').text = 'ko'
x1_ch_pu = xml.SubElement(x1_ch, 'pubDate').text = datetime.now(timezone('Asia/Seoul')).strftime('%a, %d %b %Y %H:%M:%S %z')
x1_ch_ge = xml.SubElement(x1_ch, 'generator').text = 'ivps.kr'
x1_ch_ma = xml.SubElement(x1_ch, 'managingEditor').text = item['tistory']['item']['blogs'][i]['nickname']
x1_ch_im = xml.SubElement(x1_ch, 'image')
x1_ch_im_ti = xml.SubElement(x1_ch_im, 'title').text = item['tistory']['item']['blogs'][i]['title']
x1_ch_im_ur = xml.SubElement(x1_ch_im, 'url').text = item['tistory']['item']['blogs'][i]['profileImageUrl']
x1_ch_im_li = xml.SubElement(x1_ch_im, 'link').text = item['tistory']['item']['blogs'][i]['url']
x1_ch_im_de = xml.SubElement(x1_ch_im, 'description').text = item['tistory']['item']['blogs'][i]['description']
### <==
nickname = item['tistory']['item']['blogs'][i]['nickname']
totalCnt = item['tistory']['item']['blogs'][i]['statistics']['post']
print('### post : ' + totalCnt) ### 포스팅 갯수
pages = int ( math.ceil ( float(totalCnt) / float(count) ) )
for j in range(pages): ### 총 페이지 만큼 반복
page = j+1
print('### Page : ' + str(page) + ' of ' + str(pages) + ' ###')
try:
r3 = rs.get(URL_3, params=params_3(access_token, blogName, page, count))
print('### Open API, Blog List Url : ' + str(r3.url))
xmlList = xml.fromstring(r3.text.encode(r3.encoding))
#xml.dump(xmlList)
for parent in xmlList.getiterator('post'): ### 목록에서 postId 추출
post_id = int( parent.find('id').text )
visibility = int( parent.find('visibility').text )
if(visibility in (2,3)): ### 2:??, 3:발행 게시글
try:
r4 = rs.get(URL_4, params=params_4(access_token, blogName, post_id))
print('### Open API, Blog Desc Url, postId(' + str(post_id) + ') : ' + str(r4.url))
xmlDesc = xml.fromstring(r4.text.encode(r4.encoding))
#print(xml.dump(xmlDesc))
for desc in xmlDesc.getiterator('item'): ### 상세내용 추출
x2_it = xml.SubElement(x1_ch, 'item')
x3_ti = xml.SubElement(x2_it, 'title').text = parent.find('title').text
x3_li = xml.SubElement(x2_it, 'link').text = parent.find('postUrl').text
x3_de = xml.SubElement(x2_it, 'description').text = desc.find('content').text
for tag in desc.find('tags').findall('tag'): ### 카테고리 갯수 만큼 반복
x3_ca = xml.SubElement(x2_it, 'category').text = tag.text
x3_au = xml.SubElement(x2_it, 'author').text = nickname
x3_gu = xml.SubElement(x2_it, 'guid').text = parent.find('postUrl').text
x3_pu = xml.SubElement(x2_it, 'pubDate').text = parent.find('date').text
except:
print('@@@ Error : ' + str(r4.url))
else: ### 0:비공개, 1:보호
print('### Pass PostId(' + str(post_id) + ') visibility : ' + str(visibility))
except:
print('@@@ Error : ' + str(r3.url))
else:
print('### Pass blog : ' + str(blog_name))
except:
print('@@@ Error : ' + str(r2.url))
except:
print('@@@ Error : ' + str(r1.url))
except:
print('@@@ Error : ' + str(r0.url))
#xml.dump(rss)
xml.ElementTree(rss).write('/var/www/html/rss.xml') # 적당한 위치에 저장
색깔로 표시한 부분만 수정하면 됩니다.
제대로 안되면 중간 중간에 있는 주석 풀어서 디버깅 해보세요~
그리고 너무 빈번한 Open API 호출을 하면 트래픽 부하로 차단이 될 수도 있습니다.
그런 경우엔 해당 url 을 건너 뛰고 진행하시면 됩니다.
'티스토리' 카테고리의 다른 글
[티스토리] Python Open API 이용 블로그 및 이미지 백업하기 (0) | 2018.12.26 |
---|---|
[티스토리] Python 으로 sitemap.xml 만들기 (0) | 2018.12.21 |
[티스토리] 오픈 API 로 블로그 목록 백업하기 (0) | 2018.12.14 |
티스토리 보안서버 SSL 적용 (1) | 2018.08.24 |
티스토리 Flash Player 허용방법 (0) | 2017.07.02 |