Kindle 용 Calibre Custom News Recipe 만들기
Calibre 의 뉴스 fetch 기능을 이용하면, 미국에서 kindle 3G 망을 이용해서 신문을 구독하는 것 부럽지 않게 kindle 로 신문을 구독할 수 있습니다.
그리고 미국의 유명 신문과 잡지, 몇몇 blog 들은 이미 만들어진 recipe 가 있으므로 그냥 자동으로 구독하도록 설정만 해주면 됩니다. 그러면 calibre 를 실행하고 kindle 을 연결하는 순간 뉴스가 자동으로 kindle 에 복사됩니다.
하지만 만들어진 recipe 가 없을 경우, calibre 의 메뉴중 [Fetch News]->[Add a custom news source] 에서 신문사 홈페이지에서 제공하는 rss 주소를 등록하고 몇가지 간단한 설정을 하면 새롭게 만들 수 있습니다. 그런데 몇몇 신문사 페이지 들의 경우에는(특히 한글신문사) 홈페이지에 지나치게 중첩된 table 을 tag 를 많이 쓰거나, 표준을 지키지 않은 관계로 생성된 구독 파일을 kindle 에서 보면 표가 깨어져 보기 불편합니다.
그럴 경우에 custom 뉴스 recipe 를 만들어야 합니다. 여기서는 custom recipe 를 만드는 방법을 정리해 봅니다.
calibre 는 거대한 document 관련된 python library 와 실행파일들의 집합입니다.
따라서 뉴스 구독등을 위한 custom recipe 를 만드는 것 또한 python 으로 작성되어 지므로 python 의 기본적인 문법과 기초적인 library 사용법과 html 구조에 대해서 대략 알고 있다고 가정합니다.
calibre 매뉴얼 페이지에 더 상세한 내용이 있으므로, 여기에서는 정직한 사람들이 만드는 정통 주간지인 시사인 recipe 를 만드는 것을 따래해 봅니다. 또한 calibre 가 설치된 폴더의 resources/recipes 아래에 가면 미리 만들어진 recipe 들이 많이 있으므로 이것을 읽어보는 것도 많은 도움이 됩니다.
시사인 recipe는 미리 작성된 것을 down 받아서 사용하실 수 있습니다.
0. 준비
- Kindle (DX)
제가 가지고 있는게 DX 밖에 없으나 어떤 버전도 상관없을 듯 합니다.
- 최신버전의 Calibre
- Kindle for PC
Calibre 의 mobi viewer 가 약간의 버그인지는 모르지만, kindle 에서 보여지는 화면과 서로 틀립니다. Kindle for PC 를 받아서 mobi viewer 로 쓰시면 매번 kindle 로 파일을 옮기지 않고도 kindle 에서 어떻게 보여질지 확인할 수 있습니다.
1. Recipe 파일 생성
좋아 하는 편집기를 열어 확장자가 recipe 인 빈 파일을 만듭니다. 저는 d 드라이브에 sisain.recipe 을 만듭니다. 모든 뉴스 recipe 는 BasicNewsRecipe class 를 상속받아서 몇몇 함수를 override 하는 형태로 되어 있습니다. 속칭 template pattern 이라고도 하죠
7: oldest_article =100 # 최장 몇일 전까지의 뉴스를 가지고 파일을 생성할 것인지 지정합니다.
8: max_articles_per_feed = 100 # 최대 몇개까지의 뉴스를 가지고 파일을 생성할 것인지 지정합니다.
여기까지만 해도 일단 뉴스 파일은 만들어 집니다
2. Converter 실행하기
cmd 창을 열어서 calibre 가 설치된 folder 로 이동합니다.
C:\Program Files\Calibre2>dir ebook-convert.exe
Volume in drive C has no label.
Volume Serial Number is B012-43F7
Directory of C:\Program Files\Calibre2
2009-12-26 07:47 24,576 ebook-convert
1 File(s) 24,576 bytes
0 Dir(s) 10,042,191,872 bytes free
C:\Program Files\Calibre2>ebook-convert d:\sisain.recipe d:\output_dir\out.mobi -vv --test
-vv 는 debug 옵션이고 --test 는 rss feed 의 일부만 가지고 테스트 합니다.
d:\output_dir\out.mobi 파일이 만들어 지고 kindle for pc 에서 읽을 수 있으면 일단 기본 설정은 완료된 것입니다.
(제가 테스트한 0.6.30 버전의 경우 에러가 발생하는데, url quote 를 잘 못처리하는 것 같기도 하였습니다. 만일 에러가 발생한다면, 제가 수정한 simple.py 를 Lib\site-packages\calibre\web\fetch 에 복사하고 사용하시면 됩니다)
3. Print Version 사용하기
RSS 에 있는 link 는 뉴스 웹페이지의 페이지를 가리키고 있습니다. 이 파일을 가지고 작업을 해도 되지만, 페이지에 print 기능이 있으면 print link 를 가져와서 사용하면 html 을 parsing 하기 쉽습니다.
6070 용팔이 어르신의 하루 를 잘 찾아보시면 "프린트" 링크를 찾을 수 있습니다.
원래 URL http://www.sisain.co.kr/news/articleView.html?idxno=6107
프린트 URL http://www.sisain.co.kr/news/articlePrint.html?idxno=6107
보시면 idxno 뒤의 값이 같으므로, 해당 기사번호를 가져와서 프린트 버전의 url 로 변환하도록 code 를 설정해 줍니다. print_version method 를 override 하시면 됩니다. parameter 은 original url 입니다.
여기까지 저장한 후 실행하면 조금은 더 깔끔한 화면을 볼 수 있습니다. 여기까지 보여지는 결과가 만족하면 6. Calibre 에서 Load 하기로 바로 넘어가시면 됩니다.
또한 여기에 아래 class property 만 잘 지정해도, 사실 90% 이상의 뉴스 사이트는 대부분 해결할 수 있습니다.
div tag 에서 class=advert 인 node 를 제거합니다.
remove_tags = [dict(name='div', attrs={'class':'advert'})]
id=content 인 tag 뒷부분을 제거합니다.
remove_tags_after=[dict(id='content')]
id=content 인 tag 직전까지 제거합니다.
remove_tags_before=[dict(id='content')]
style 과 font attribute 들을 제거합니다.
remove_attributes=['style', 'font']
id=content 와 id=heading 인 tag 와 그 child 만 가지고 작업합니다.
keep_only_tags=[dict(id=['content', 'heading'])]
여기서 부터는 고급(?) 과정으로 BeautifulSoap 을 왠만큼 다루거나 이해할 수 있어야 합니다.
4. html parsing
html 의 내용을 바꾸는 여러가지 방법이 있지만, 개인적으로 선호하는 방법은 preprocess_html method 를 override 해서 내용을 변경하는 방법입니다.
저는 새로운 html body 내부를 build 한 후, 기존 body 를 replace 하는 방법을 씁니다. preprocess_html 의 soup parameter 는 프린트 버전의 url 에서 소스보기를 한 전체 html 내용이 BeautifulSoup 객체로 들어 있습니다.
30~33: 아래 틀을 만듭니다.
<body><h3>[제목]</h3><h4>[소제목]</h4><p>[기사정보]</p>[본문내용]</body>
36: 기사에서 기사 작성 시간과, 기자 정보를 가져옵니다.
37: 기사에서 제목은 class=view_t 인 tag 의 내부에 있으므로 가져와 h3 내부에 채웁니다.
38~40: class=view_sub_t 인 부제목을 찾아서 있으면 h4 내부에 채웁니다.
42,43: 위에서 가져온 기사 작성시간과 기자정보를 p 내부에 채웁니다.
45: 기사 본문만 가져 옵니다
47~49: body 를 아래와 같이 구성합니다.
<body><h3>6070 용팔이 어르신의 하루</h3><h4>6070 용팔이 오명 듣는 어버이연합의 실체 ③</h4>
<p><span style="font-size:8pt; letter-spacing:-0.3;">
<font face="돋움" color="#666666">
[119호] 2009년 12월 25일 (토) 19:02:54
</font>
</span>
<span style="font-size:8pt; letter-spacing:-0.3;">
<font face="돋움" color="#666666">
장일호 기자
</font>
<img src="/image2006/default/btn_sendmail.gif" border="0" />
<font face="arial" color="#666666">
ilhostyle@sisain.co.kr
</font>
</span></p></body>
51,52,61~77: 시사인의 경우 image 가 table 로 감싸져 있는데, 텍스트등은 바로 가져오고, table 에서 이미지만 뽑아와서 본문에 붙입니다.
55~59: 기존의 body 를 가져와서 새로만든 body 로 변경한 후 return 합니다.
5. 표지 만들기 - optional
14~17: 꼭 없어도 됩니다만, 표지 이미지 file 있는 url 을 지정해 줍니다. 시사인의 경우는 딱히 룰이 없어 그냥 때려 맞추었습니다.
6. Calibre 에서 Load 하기
calibre 의 메뉴중 [Fetch News]->[Add a custom news source] 왼쪽 하단의 [Load recipe from file] 을 선택해서 작성한 파일을 선택하시면 됩니다
[Fetch News]->[Schedule News Download] 에서 새로 추가한 recipe 를 주기적으로 받도록 설정합니다.
그 이외에도 override 가능한 method 들이 궁금하시면 linux 버전을 다운 받으시면 source 파일을 볼 수 있으므로 BasicNewsRecipe class 의 소스코드를 보시면 좀더 복잡한 작업을 하실 수 있습니다.
kindle 에서 보는 화면은 다음과 같습니다.

3 개의 댓글:
올려주신 강좌 감사합니다. 역시 기초가 없어서 그런지 어렵군요.
질문 한가지 드립니다.
기사가 페이지번호로 나누어져 있는 경우, 예를 들면 기사하단에 1 2 3 으로 계속 기사본문이 나눠져 있는 경우에 자동(?)으로 가져와서 기사본문을 붙이는 방법이 있을까요? 기사본문이 aaa_1.html / aaa_2.html / aaa_3.html 이라고 할때, 3페이지를 모두 가져와서 aaa.html로 묶을 수 있는 방법 말입니다. 힌트 좀 내려주십시요
자동으로 기사 본문을 붙이는 방법은 없을 것 같고, preprocess_html 에서 하위페이지가 있는지 읽어서 붙이는 조금은 복잡한 python 코드가 필요할 것 같습니다.
어떤 신문사 rss 를 기반으로 만드시려는지 알려주시면 좀더 자세한 방법을 생각해 볼 수 있겠네요.
글이 좋아서, 그리고 시간날 때 자세히 해 보고 싶어서 제 블로그에 스크랩했습니다. 출처를 밝혔습니다.
댓글 쓰기 |