2009/05/07

groovyスクレイピング & grape

Groovyでスクレイピングしてみる(NekoHTML編) - No Programming, No Life

理系のための恋愛論をGroovyでスクレイピングする! - すらすら はてな

の記事が面白かった。

  • XmlSlurper
  • XmlParser

を使用するとxmlを厳密にチェックするため、htmlの解析ができなかったけれども、nekohtmlっていうライブラリを利用するとあいまいなhtmlを解釈してパースしてくれるのでいろいろできるよ、っていうエントリ。

最近、いまさらながら

GCR #16 「Groovy なう&ふゅーちゃー、それからのGroovy」 - Grな日々(uehajの日記)

を見て、grapeの機能が便利だな、と思ったのとokuさんがgrapeライブラリ探すにはMaven Repository: Search/Browse/Exploreを利用するといいよと教えてくれたので(いずれもいまさらですが・・・)ちょっとスクレイピングのエントリに書き加えてみた。

#!/usr/bin/env groovy
import static java.lang.System.*
import org.cyberneko.html.parsers.SAXParser

// over proxy ..
if( getProperty("http.proxyUser") && getProperty("http.proxyPassword") ){
    def pw = new PasswordAuthentication(
        getProperty("http.proxyUser"),
        getProperty("http.proxyPassword").toCharArray()
    )
    Authenticator.default = { getPasswordAuthentication:{ pw } } as Authenticator
}

// grape
@Grab(group = 'nekohtml', module='nekohtml', version='latest.integration')
class Dummy{}

//--------------------MAIN LOGIC--------------------
def MYCOM = "http://journal.mycom.co.jp/";
def allPage = [];
def parser = new XmlSlurper(new SAXParser()) 

def indexPage = parser.parse("${MYCOM}column/rikei/index.html")
def td= indexPage.'**'.findAll{
    it.name() == 'TD'
}

td.eachWithIndex{ it, index ->
    def number = "${td.size() - index}".padLeft(3,'0');
    allPage << [
        title:"第${number}回_" 
                + it.A.text().replace('?','?') .replace('\"','”').replace('/',"/")
        ,url: "${MYCOM}${it.A.@href}"
    ]
}

new File("rikei").mkdir();

allPage.each{ page ->
    println "downlaoding... ${page.title} ${page.url}"
    def contentPage = parser.parse(page.url)
    def content = contentPage.'**'.find{
        it.name()=='DIV' && it.@class=='articleContent'
    }.P.collect{
        it.text() + '\n'
    }.join('\n')
    new File("rikei/${page.title}.txt").newOutputStream() << content
}
//--------------------MAIN LOGIC--------------------

6行目から12行目はただ単に社内のfirewallを超えたいがための設定。(家でやれよ、という突っ込みはなしで

16行目のクラス定義はアノテーションのために必要なのでとりあえず追記。かっこ悪いけど。

これでjarファイルは自動的にダウンロードされた。

0 件のコメント:

コメントを投稿