読者です 読者をやめる 読者になる 読者になる

ottatiのブログ

無職学生がネットにクソアプリをまき散らしていく様子

【Python】GitHub式MarkdownをHTMLに変換し、更にJavaScriptとかの危険なタグを除去しよう

f:id:ottati:20150103125718g:plain     🍣

Markdownは最高

僕はMarkdownは最高なマークアップ言語の一つだと思います。なぜならGitHubが全般的に採用しているからです。この文章も全てMarkdownで記述されています。こうやってブログを書いていられるのもMarkdownが使えるからだと思っています。

f:id:ottati:20140912003844p:plain

普通にマークダウン

python-markdownを使います。pip install markdownしてfrom markdown import markdownしてhtml = markdown(raw)でポコンとHTMLが生まれます。

GFMを扱う

そして世の中にはGitHubMarkdownというものがあります。GitHub Flavored Markdownです。GFMと略されます。「Markdownがここまで普及したのはGitHubのおかげ」というのは過言ではないと聞きます。

お客さまの声

Markdownが便利すぎて生きるのが辛い http://b.hatena.ne.jp/fakechan/20130613#bookmark-132564918

今回はPythonでGFMをレンダリングします。

f:id:ottati:20140912011233p:plain

py-gfmを使います。

GitHub - googlearchive/py-gfm: This repository is unmaintained. Please see Zopieux/py-gfm for the new canonical repository.

「なぜDartの人達がPythonMarkdown変換器を作っているのか」という疑問が頭をかすめたような気がするとか、そういうのは置いといてとりあえずインストールします。

pip install git+https://github.com/dart-lang/py-gfm

使います

html = markdown(raw, extensions=['gfm'])

幸せ。

危険なタグの排除

こんなことにならないようにしたいところではありますね。

実はlxmlにはハッピーな機能があってこれを使うと下が下下になります。

>>> html = '''\
... <html>
...  <head>
...    <script type="text/javascript" src="evil-site"></script>
...    <link rel="alternate" type="text/rss" src="evil-rss">
...    <style>
...      body {background-image: url(javascript:do_evil)};
...      div {color: expression(evil)};
...    </style>
...  </head>
...  <body onload="evil_function()">
...    <!-- I am interpreted for EVIL! -->
...    <a href="javascript:evil_function()">a link</a>
...    <a href="#" onclick="evil_function()">another link</a>
...    <p onclick="evil_function()">a paragraph</p>
...    <div style="display: none">secret EVIL!</div>
...    <object> of EVIL! </object>
...    <iframe src="evil-site"></iframe>
...    <form action="evil-site">
...      Password: <input type="password" name="password">
...    </form>
...    <blink>annoying EVIL!</blink>
...    <a href="evil-site">spam spam SPAM!</a>
...    <image src="evil!">
...  </body>
... </html>'''
>>> from lxml.html.clean import clean_html
>>> print clean_html(html)
<div><style>/* deleted */</style><body>

   <a href="">a link</a>
   <a href="#">another link</a>
   <p>a paragraph</p>
   <div>secret EVIL!</div>
    of EVIL!


     Password:
   annoying EVIL!<a href="evil-site">spam spam SPAM!</a>
   <img src="evil!"></body></div>

こいつfrom lxml.html.clean import clean_htmlですね。このclean_htmlを使えば"最低限のいい感じ"になるんです。

pip install lxmlして早速html = clean_html(html)しましょう。タグをremove_tagsとして指定したりもできます。内容もまるごと消し去りたい場合はkill_tagsコードみるとかなり自由度高いですね。

最終的に

元気な赤ちゃんが生まれました。

ちなみにpip install pygmentsしてCSSを読み込むだけでhtmlのコードらへんがカラフルになりますヽ(´ー`)ノ

以上です。

f:id:ottati:20140912013713p:plain