-
티스토리 포스팅 글, 이미지 백업 (with 파이썬)코딩 연습/코딩배우기 2021. 9. 6. 23:44반응형
티스토리 포스팅 글, 이미지 백업 (with 파이썬)
티스토리(tistory) 백업이 필요해서 파이썬(스크래핑)으로 블로그 포스팅 글과 이미지를 PC에 저장하기 도전
왜, 이 짓을 했을까..?
티스토리(Tistory) 블로그를 한 지 1년이 지나면서, 가끔 데이터 백업을 어떻게 하나 고민을 한 적이 있었는데 이제 파이썬을 어느 정도 공부를 했으니 도전해볼 때가 된 것 같아서 이런 짓(?)을 했다.
포스팅 글에 대해 아무것도 모르고 시작하던 1년 전에는 PC에 원본을 저장하기도 했었는데, 그것도 잠시…
시간이 지나다보니 포스팅한 후 원본은 어디에 팔아먹었는지 보이지가 않는다.티스토리도 옛날에는 백업 기능이 있었다고 하던데…
그랬으면 이런 수고(?)를 안해도 되었을텐데...
포스팅 글이 그렇게 좋은 건 아니지만,
한 땀 한 땀 써 놓은 내 글과 이미지가 내 PC에 저장되어 있는 것도 좋을 것 같아서 파이썬 공부삼아 고민해가면서 하나씩 시도를 좀 해봤다. (글은 텍스트(.txt)로, 이미지는 올린 크기로 받기)
일단 코딩한 것이 동작하는 환경과 그 내역을 살펴보면,
-북클럽(Book Club) 스킨에서 카테고리 7~8개 만들고 포스팅 중
-포스트 주소는 숫자로 설정해서 사용 중임여기서, 초보자의 기술적 한계로 인해 포스트 주소가 문자로 설정된 경우는 이후에 해결할 문제로 남겨둘 수 밖에 없었다. (나중에 다시 시도를 할 목표가 생김)
개발자도구(F12)에서 html 코드를 보고
-requests, BeautifulSoup를 통해 스크래핑 진행했으며,
-PIL Image를 통해 이미지 다운로드 시 안보이는 확장자 문제를 해결해봤다. (맞는지는 모름… 나오긴 함)
이미지는 src에 확장자(.jpg .png)까지 정확하게 된 것도 있었지만, 다음과 같은 형태로 포함된 URL을 가지고 있는 것도 있었다.
<img srcset="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=http%3A%2F%2Fcfile1.uf.tistory.com%2Fimage%2F993693465F20BB0F1FAFB6" src="https://t1.daumcdn.net/cfile/tistory/993693465F20BB0F1F" //i1.daumcdn.net/thumb/C176x120/?fname=https://t1.daumcdn.net/cfile/tistory/99400A3F5F21057413
PIL Image로 이미지 정보를 찾으면,
img_url: https://t1.daumcdn.net/cfile/tistory/992895395F2040A804 img_format: PNG imge_size: (830, 1019) len(이미지): 41568
소스 코드는
from bs4 import BeautifulSoup import requests import os from PIL import Image def tistory_backup(post_num): for num in range(1, post_num + 1): url = 'https://본인의 티스토리 URL/' + str(num) response = requests.get(url) soup = BeautifulSoup(response.text, 'lxml') ### 포스팅 글 제목 titles = soup.select_one('#content > div.inner > div.post-cover > div > h1') ### 등록일 date = soup.select_one('#content > div.inner > div.post-cover > div > span.meta > span.date') if not titles or not date: continue print(titles.text) print(date.text) ### 포스팅 내용 entry_content = soup.find('div', {'class':'entry-content'}) print(entry_content.get_text()) res = requests.get(url) soup_img = BeautifulSoup(res.content, 'lxml') imgs = soup_img.select('img[src^=https]') # https 로 시작하는 src, '//'로 시작하는 src 제외시킴 print(f'이미지 수 : {len(imgs)}') # print(imgs) # 저장 디렉토리 만들기 if not os.path.exists('tistoryBackup'): os.mkdir('tistoryBackup') if not os.path.exists('tistoryBackup/post_' + str(num)): os.makedirs('tistoryBackup/post_' + str(num)) cnt = 1 for img in imgs: img_url = img['src'] ## pillow.Image로 이미지 format 알아내기 imageObj = Image.open(requests.get(img_url, stream=True).raw) img_format = imageObj.format imge_size = imageObj.size print(f'img_url: {img_url}') print(f'img_format: {img_format}') print(f'imge_size: {imge_size}') print(f'os.path.basename(img_url): {os.path.basename(img_url)}') res_img = requests.get(img_url).content print(f'len(이미지): {len(res_img)}') # requests의 .content는 bytes 타입을 리턴함 if img_url.split('.')[-1] in ['png', 'jpg']: img_name = str(num) + '_' + str(cnt) + '_' + os.path.basename(img_url) else: img_name = str(num) + '_' + str(cnt) + '_' + 'no_filename_img.' + img_format print(img_name) if len(res_img) > 100: # 이미지 용량이 00 bytes 이상인 것만 with open('./tistoryBackup/post_' + str(num) + '/' + img_name, 'wb') as f: f.write(res_img) cnt += 1 title_content = titles.text + '\n' + date.text + '\n' + entry_content.get_text() filename = str(num) + '_tistory_title_content.txt' with open('./tistoryBackup/post_' + str(num) + '/' + filename, 'w', encoding='utf-8') as f: f.write(title_content) tistory_backup(20)
tistory_backup(20) 실행 시, 20은 포스트 주소의 숫자.
즉, https://abc4u.tistory.com/1 ~ https://abc4u.tistory.com/20 까지의 포스트 url을 대상으로 추출한다는 의미이며, 본인의 최근 포스팅 번호를 넣으면 1번 부터 최근 번호까지 전체가 추출됨티스토리 백업 소스코드를 실행하면 위 탐색기 이미지처럼 폴더를 생성하고, 글은 .txt 파일로 저장하고 해당 포스트에 있는 이미지전체는 이름을 다시 만들어져서 저장된다.
▷ 티스토리, 다음, 네이버 블로그 하나씩 다운로드하는 프로그램
반응형'코딩 연습 > 코딩배우기' 카테고리의 다른 글
VS Code에서 파이썬 가상환경 만들기 (1) 2021.10.11 파이썬 장고(django) 웹 프로그래밍 - 웹 페이지 만들기 # 1 (0) 2021.09.23 파이썬 datetime 모듈과 장고(django) 모델(models) 시간 (0) 2021.09.03 쿠팡 파트너스 상품 링크 상세정보 URL로 들어가기 - 오류 발생 (0) 2021.08.27 API를 잘 모르면서 해본 '쿠팡 파트너스 API' 실습 (0) 2021.08.23