LoginSignup
7
5

More than 5 years have passed since last update.

Common LispでURLからページタイトルを取得する

Last updated at Posted at 2016-03-17

動機

URLをメモするときに、ページタイトルがあったら便利だなと思ったので作りました。これまでは、javascriptでpukiwiki用に出力するbookmarkletを自作していたのですが、ページごとにbookmarkletを起動させないといけないのが億劫になりました。

このごろCommon Lispにハマっているのでその練習も兼ねて。

環境

  • Mac OS X El captain(10.11.3)
  • SBCL 1.3.2

必要ライブラリ

gistへのリンク

Gistにコードをまとめました。

httpレスポンスを文字列として取得

Drakmaで帰ってきたhttpレスポンスのbodyは、vectorの場合と文字列の場合があります。:force-binaryを使うことで、vectorで返してもらいます。

(drakma:http-request url :force-binary t)

ここで得られたvectorをguessというライブラリで文字コード判別します。

(guess:CES-GUESS-FROM-VECTOR input-vector :jp)

文字コードが判別できたら、babelというライブラリで、文字列に変換します。ここで判別された文字コード名と、babelで指定するシンボルは異なる場合があるので注意が必要です(例 EUC-JPなら:eucjp)。

(babel:octets-to-string input-vector :encoding encoding)

DOMに変換

titleタグの中に入っている文字を取得したいので、plumpというライブラリで、文字列をDOMに変換します。

(plump:parse html-body)

DOMからタイトルを取得

plumpのDOMオブジェクトから、clssというライブラリでtitleタグを抽出します。

(clss:select "title" dom)

抽出されたオブジェクトはvectorですので、map 'listで変換しつつ、各要素にplump:textで文字列を取得します。

(map 'list (lambda (val) (plump:text val)) (clss:select "title" dom))

実行例

上記で説明したものを組み合わせた、get-titleという関数を使ってみます。下の例はUTF-8のサイトのみに適用していますが、Shift-JIS、EUC-JPのサイトでも無事取得できました。

get-title.lisp
(get-title "https://ja.wikipedia.org/wiki/Common_Lisp")
;;=>("Common Lisp - Wikipedia")
(get-title "http://www.sbcl.org/")
;;=>("About - Steel Bank Common Lisp")
(get-title "http://tips.cddddr.org/common-lisp/")
;;=>("逆引きCommon Lisp")

複数のURLを渡す

mapcanを使って、複数のURLを処理することができます。

get-titles.lisp
(mapcan #'get-title '("https://ja.wikipedia.org/wiki/Common_Lisp" "http://tips.cddddr.org/common-lisp/")))
;;=>("Common Lisp - Wikipedia" "逆引きCommon Lisp")
7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5