日本語を含んだURLのページ取得を諦めた【tumblr/random】


Hubotでランダムなページへ移動するページ(/random)へアクセス
移動後のページをパースして返す…
という機能を作ろうとした。
しかし
robot.http (node-scoped-http-client)
request
どちらも試したが、
リダイレクト先のURLに日本語が含まれていた場合、正常に読み込みができなかった。
ステータスは400 Bad requestになるし、リダイレクト先のURLを出力してみたら文字化けていた。

日本語の部分を削ったり、URLパラメーターに変換したりしてみたが、
加工したURLから元の日本語付きURLにリダイレクトで戻されるので、堂々巡りだった。

今回は別経路からほぼ同一ページが英数字だけのURLで取得できたが、
普通のサイトでは無理だろうし、ほぼ諦め中


具体的にはtumblrの/random。
タイトルがURLに入るようで、日本人の場合に多い。
適当にサイトを上げると…
よりぬきデイリーポータルZにします(日本語タイトルが多そうな検索トップ)

http://dailyportalz.tumblr.com/
なので、
http://dailyportalz.tumblr.com/random
にアクセスすると
ブラウザでは
http://dailyportalz.tumblr.com/post/47437845065/niftyデイリーポータルzぬいぐるみに剃りこみを入れる
なURLにリダイレクトされます。

robot.httpで書くと大体以下な感じ。
robot.httpは手動でリダイレクト先に飛ばないといけないが、
requestなら自動で飛んでくれるように見えた。


    robot.respond /daily/i, (msg) ->
        robot.http('http://dailyportalz.tumblr.com/random').get() (err, res, body)->
            unless err?
                if res.headers.location?
                    robot.http(res.headers.location).get() (err, res, body)->
                        unless err?
                            console.log('成功')
                            console.log(body)
                        else
                            console.log('リダイレクト後エラー')
                            console.log(err)
                else
                    console.log('リダイレクトなし')
                    console.log(body)
            else
                onsole.log('randomエラー')
                console.log(err)

結果は


成功
<html><body><h1>400 Bad request</h1>
Your browser sent an invalid request.
</body></html>

これが英語のみの場合、
たとえば
Cats of Tumblr
なら
http://catsof.tumblr.com/
http://catsof.tumblr.com/random
http://catsof.tumblr.com/post/66245080562/postmodernism-i-dont-know-why-frank-insisted
なので、先ほどのコードからURLを書き換えると、
400ではなく通常のHTMLのbodyが取得できる。

URL書き換えのみ

    robot.respond /cat/i, (msg) ->
        robot.http('http://catsof.tumblr.com/random').get() (err, res, body)->
            unless err?
                if res.headers.location?
                    robot.http(res.headers.location).get() (err, res, body)->
                        unless err?
                            console.log('成功')
                            console.log(body)
                        else
                            console.log('リダイレクト後エラー')
                            console.log(err)
                else
                    console.log('リダイレクトなし')
                    console.log(body)
            else
                onsole.log('randomエラー')
                console.log(err)