컴언

파이썬 객체를 파일로 저장하는 방법 - Serialization (직렬화)

공부/Python

파이썬 객체(Object)를 파일로 출력해서 필요할 때 마다 불러와 쓸 수 있는 방법을 소개한다. 진짜 간단함!


용어 정리: 직렬화와 역직렬화

쉽게 설명하면

직렬화 (Serialization) : 객체를 파일로 내보냄
역직렬화 (Deserialization) : 파일로 내보낸 객체를 다시 읽어들임


파이썬에서는 어떻게?

pickle 이라는 파이썬 표준 라이브러리를 사용하면 된다.


1. 직렬화 (파이썬에서는 pickling 이라고 주로 부른다.)

pickle.dump(내보낼 객체, 파일)



2. 역직렬화 (파이썬에서는 unpickling 이라고 주로 부른다.)

pickle.load(파일)



[자작] web2kindle: 웹페이지를 pdf 로 저장해 킨들 이메일로 보내기

공부/Python

Kindle 이메일에 문서를 보내면 자동으로 동기화하는 기능 아시죠?(참고: Send to Kindle by E-mail) 




저는 이 기능을 인터넷 기사나 블로그 글 같은 것을 옮길 때 쓰는데, 매번 pdf 변환해야하고 이메일 로그인해서 킨들 이메일로 보내야하고 여간 귀찮은 일이 아니더군요. 그래서 킨들로 바로바로 쉽게 보내기 위해 간단한 Python 스크립트를 만들어봤습니다. 


Python 버전은 3.x 이고 사용한 모듈은 pdfkit(웹페이지를 pdf 로 바꿔줌), smtplib(SMTP 서버를 이용해 간단히 이메일 보내기), lxml 입니다. 시간이 되면 제 GitHub 에 꾸준히 개선판을 올리겠습니다. (아직 기능적으로 많이 부족해요 ㅠㅠ 참고만 해주세요)


사용법: 먼저 네이버/다음/지메일 계정으로 로그인한 다음, 본인의 Kindle 이메일 계정을 쓰고 킨들에 전송하고자 하는 사이트의 URL 을 입력하면 됩니다.

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import pdfkit
import getpass
import smtplib
import lxml.html

from email.mime.multipart import MIMEMultipart
from email import encoders
from email.message import Message
from email.mime.base import MIMEBase

NAVER_SMTP = "smtp.naver.com"
NAVER_SMTP_PORT = 587
NAVER_SUFFIX = "@naver.com"

DAUM_SMTP = "smtp.hanmail.net"
DAUM_SMTP_PORT = 465
DAUM_SUFFIX = "@hanmail.net"

GMAIL_SMTP = "smtp.gmail.com"
GMAIL_SMTP_PORT = 587
GMAIL_SUFFIX = "@gmail.com"

# store the webpage in a byte variable
def html2pdf(url):
	# convert the webpage to pdf
	options={
       	'page-size': 'A4',
        'margin-top': '0',
        'margin-right': '0',
        'margin-left': '0',
        'margin-bottom': '0',
        'encoding': "UTF-8",
        'no-outline': None,
    }
	return pdfkit.from_url(url, False, options=options)

def get_title_from_webpage(url):
	# Get the title from url
	t = lxml.html.parse(url)
	return t.find(".//title").text

def send_pdf_to_kindle(server, sender, receiver):
	body = MIMEMultipart()
	body["From"] = sender
	body["To"] = receiver
	body["Subject"] = ""

	url = input("킨들에 전송하고자 하는 url을 입력하세요.")

	title = get_title_from_webpage(url)
	try:
		pdf = html2pdf(url)
	except:
		print("pdf 로 변환하는데 오류가 발생했습니다.")
	#pdf = pdfkit.from_url(url, False)
	#file = html2pdf_as_file(url)

	#file = open("out.pdf", "rb")
	attachment = MIMEBase("application/pdf", "application/x-pdf")
	attachment.set_payload(pdf)
	#attachment.set_payload(file.read())
	#file.close()
	encoders.encode_base64(attachment)
	attachment.add_header("Content-Disposition", "attachment", filename= title + '.pdf')
	body.attach(attachment)

	try:
		server.sendmail(sender, receiver, body.as_string())
		print(receiver +  "로 전송 완료")
		server.quit()
	except:
		print('메일을 전송하는데 오류가 발생했습니다.')

def main():
	# initialize configurations for sending email
	while True:
		email_provider = input("어떤 이메일을 사용할까요? 1. 네이버 2. 다음 한메일 3. 구글 지메일")
		if email_provider == '1':
			smtp_server = NAVER_SMTP
			smtp_port = NAVER_SMTP_PORT
			smtp_suffix = NAVER_SUFFIX
			USE_SSL = False
			break
		elif email_provider == '2':
			smtp_server = DAUM_SMTP
			smtp_port = DAUM_SMTP_PORT
			smtp_suffix = DAUM_SUFFIX
			USE_SSL = True
			print("Kindle 허용 이메일에는 @hanmail.net 이메일로 추가해주세요.")
			break
		elif email_provider == '3':
			smtp_server = GMAIL_SMTP
			smtp_port = GMAIL_SMTP_PORT
			smtp_suffix = GMAIL_SUFFIX
			USE_SSL = False
			break
		else: 
			print("잘못 입력하셨습니다.")
	if USE_SSL:
		server = smtplib.SMTP_SSL(smtp_server, smtp_port)
	else:
		server = smtplib.SMTP(smtp_server, smtp_port)
	username = input("로그인 ID를 입력해주세요.")
	sender_email = username + smtp_suffix
	password = getpass.getpass("비밀번호를 입력해주세요.")
	server.starttls()
	server.login(username, password)
	print("로그인 되었습니다.")
	#print("로그인 실패")

	receiver_email = input("Kindle 이메일 계정을 입력하세요.")

	send_pdf_to_kindle(server, sender_email, receiver_email)

if __name__ == "__main__":
    main()