CommonLispでスクレイピング

Survival Common Lisp にスクレイピングの記事があったのでせっかくだし、軽く書いてみるかーってことで書いた.


本書では文書クラスタリングなどしていたが、そこまでの元気がなかったので、対象のページにある画像をすべてダウンロードするところまで書いた.

コードは以下:

(ql:quickload :dexador)
(ql:quickload :trivial-download)
(ql:quickload '(:plump :clss))

(defparameter *url* "https://portfolio.takeokunn.xyz/")
(defparameter *download-url* "~/Desktop/tmp/")

(defparameter *root-node* nil)
(defparameter *img-node* nil)

(defun concat-node-text (node)
    "example: (concat-node-text *root-node*)"
    (let ((text-list nil))
        (plump:traverse node
            (lambda (node) (push (plump:text node) text-list))
            :test #'plump:text-node-p)
        (apply #'concatenate 'string (nreverse text-list))))

(defun main ()
    (let ((html-source (dex:get *url*)))
        (setf *root-node* (plump:parse html-source))
        (setf *img-node* (coerce (clss:select "img" *root-node*) 'list))
        (mapcar #'(lambda (x)
                      (let ((src (plump:attribute x "src")))
                          (trivial-download:download (concatenate 'string *url* src) (concatenate 'string *download-url* src))))
            *img-node*)))

使用ライブラリ:

dexadorget して htmlparse して img タグを抜き出して trivial-download でダウンロードする、といった簡単なプログラムだ.

今後はDBを活用したり、文書クラスタリングをしたりなどやっていきたい.