アレクサンドル・ユユスキーのブログ

ふぁぼんが適当なことを言うブログ

朝鮮中央通信Web版大解剖、或いは初めてRubyのgemを作った話

諸君 私は北朝鮮が好きだ
諸君 私は北朝鮮が好きだ
諸君 私は北朝鮮が大好きだ

とある少佐のスピーチより

人生で初めてRubyのgemを作りました。

github.com

北朝鮮公式のニュースサイトである朝鮮中央通信APIクライアントです。gem install kcnaとかでインストールできます。
人生初のgemがこんなアレな代物ってことに思う所が無いわけではありませんが、楽しかったから良し。

経緯

全国推定3億人の北朝鮮趣味者のみなさん、こんにちは。私は今日も首領様を讃える音楽を聴いております。北朝鮮の音楽はいいぞ。

さて、日本人なら1度くらいは誰しも北朝鮮の仰々しい日本語を真似したことがあるでしょう。「定期考査をこの学校から永遠に一掃することを誓う」とか。共産趣味者はみんな「同志スターリン」とか「万国のプロレタリアート団結せよ」とか言ってますが、それの北朝鮮版です。
しかし、私はプログラマです。自分で北朝鮮の語録を使うだけでは物足りません。もし北朝鮮の日本語のデータベースがあれば、使い古された人工無脳の要領でそれっぽい日本語を生成できるだろう。そんなことを考えた私は、北朝鮮の日本語データベースに着手しました。

まず、初めに朝鮮中央テレビの字幕を採取することを考えました。リプライに使える朝鮮中央通信画像botとかで流れてくるアレです。しかし、調べていくうちに残念なことがわかりました。あの画像群はどうやらとあるYouTubeチャンネルの中の人が付けたもののようです。

www.youtube.com

このチャンネルの動画以外に、あのような字幕付きの動画が一切見当たらなかったので、間違いなさそうです。別にこのチャンネルの字幕を文字起こししても良かったのですが、これは北朝鮮公式の字幕ではないので、目的と照らし合わせればちょっと残念です。

北朝鮮の公式の機関が書いた日本語を探すと、ありました。朝鮮中央通信Web版です。

朝鮮中央通信と検索すると、http://kcna.co.jpが出てくると思いますが、そちらではありません。http://kcna.kpです。.kpドメインのサイトは初めて見ました。あとアクセスは自己責任で。普通に閲覧するだけなら特に問題は起きないと思うけど、マルウェアが置いてあったりはします。

gigazine.net

というわけで、このサイトをスクレイピングなりなんなりしてデータを取ってこようと決意したわけです。

朝鮮中央通信大解剖

さて、このサイトの使い方を調べてみましょう。もちろん開発者ツールのネットワークタブを監視しながら。

まず、トップページから適当な記事のリンク(実はリンクじゃない。後述)を踏むと、こんな画面になります。

f:id:fabonya:20170710211242p:plain

次のリストに移る青い矢印をクリックすればXHRでデータを取ってきて遷移してくれます。つまり、APIの仕様がまるわかりです。右上の謎リボンみたいなのは記事絞り込みツールです。絞り込んだ状態で矢印をクリックすると、APIのパラメータの仕様がよくわかります。

とにかく、いろんなページを渡り歩き、いろんなボタンを押しながらネットワークアクセスを監視しました。そうすればどのURLにどんなデータを送りつけるとどんなレスポンスが帰ってくるかがだいたいわかりました。

さて、このサイト、いろいろツッコミどころが満載です。主体(チュチェ)プログラミングの成果でしょうか。拡張子がkcmsfなのもちょっと変ですけど、それだけじゃありません。

まず、中途半端にJSを使っているせいで記事のパーマリンクがないという事態に。まぁTwitterでシェアなんて概念はあっちにないだろうから仕方ないのかも。

となれば、当然JSからXHRでアクセスするためのAPIみたいなのが存在するが、GETにすべきところも全てPOST。APIだけでなく、ページ遷移も全てPOST。ハイパーリンクなんてものはない。リンクに見えるものも、実はクリックするとJSが発動してPOSTで遷移するようになってます。いやマジでなんでや。北朝鮮特有の事情による要請なんだろうか。

ところで、POSTにおけるリダイレクトはいろいろ仕様と実装が混沌としていますが、307だと大抵のブラウザでもPOSTで再送信という挙動を示しますし、仕様にもそう明記されています。だからといって、しばらく通信してないと初回は307 Temporary Redirectが飛んでくる仕様は如何なものか。しかも飛ばされた先は同じURLですよ。もう一度POSTで同じところへ送れってことなんでしょうね。これもチュチェ工学による要請なんだろう。(諦め)

さて、スクレイピングするまでもなくAPIを叩けば記事のデータが手に入ります。しかし、XHRで取ってきたHTMLの断片をinnerHTMLで突っ込む実装なので、

<nobr><strong><font style='font-size:18pt;'>金正恩</font></strong></nobr>党委員長
みたいな文字列が平気で紛れ込んでます。セキュリティも何もあったもんじゃねぇな。さすが北朝鮮
というわけで、そこらへんを適当に変換してやるとプレーンテキストが得られます。

gemの実装

まず、set-cookieをちゃんと扱えるHTTPクライアントが必要です。今回はhttpclientを使いました。

github.com

XMLのパースには標準のREXMLを使いました。これくらいのことでNokogiri導入して消耗する必要はないからね。(気になる人は「nokogiri インストール」で検索してみよう。インストールに四苦八苦する先人の姿が見えます)

他に難しいことは特にありません。コードを適当に書けばそれっぽいのができます。

最後に

なんでもチュチェチュチェ言ってれば許されると思うなよ、北朝鮮同志(エンジニア)諸君!