Yahoo!PipesのFetch Pageを使ってHTTPプロキシ

Fetch Page モジュール

とある用件で、Yahoo!Pipesについて調べてたら、たまたま、
Fetch Pageというモジュールがあることを知った。


URLを渡すとページの内容(htmlソース)をJSONPとかで取得できるAPIをYahoo! Pipesで作った

Yahoo!Pipesのすごいとこ

Yahoo!Pipesのすごいとこは、グラフィカルなインタフェースというより、

  • Yahoo!(US)が提供する、(ある程度)信頼のおける
  • フィードアグリケーターWebAPI


であること、だと思う。


おそらく、明日急にサービスが無くなったりすることもないだろう。
大量のトラフィックをさばけるようにしてあるだろうし、
ダウンしっぱなしってこともないだろう。


同じような機能であっても、無名のサービスだと、そこまでは頼りにできないし、
じゃあ、自前で用意するかってことになる。
でも、Yahoo!Pipesなら割とアテにできそうな気がするし、
少なくとも試験的に始めるには十分過ぎる。

さらにすごいとこ

Yahoo!PipesJSONPでデータを取得できる点だ。
つまり、
クロスドメインでデータを取得したい時、(サーバを用意したりせずに)さくっと実現できる
ということだ。

PipesBrowser

例えば、Yahoo!Pipesを簡易的なHTTPプロキシにすることができる。


これなら、
仮に政府から検閲を受けてもサイトAを参照することが可能となる

MyPageLoader

Page Loader APIを参考に、MyPageLoaderを作った*1



実にかんたん。


あとは、いくつかGETパラメータを付けるだけ。

パラメータ 説明
url=<取得対象URL> 取得対象のURL
_render=json 出力形式にJSONを指定
_callback=<コールバック関数> コールバック関数を指定。引数にJSONデータが渡される

例えば、
http://pipes.yahoo.com/cskai4g/mypageloader?url=http%3A%2F%2Fd.hatena.ne.jp%2Ffuzzhead%2F&_render=json&_callback=jsonCallback
というかんじだ。

取得結果

返却されるJSONはこんなかんじ。

jsonCallback({
    count: 1 (number)
    ,value: {
        title: MyPageLoader (string)
        ,description: Pipes Output (string)
        ,link: http://pipes.yahoo.com/pipes/pipe.info?_id=bpTWzTGY3RGHQP2HBRNMsA (string)
        ,pubDate: Sun, 12 Oct 2008 01:51:31 PDT (string)
        ,generator: http://pipes.yahoo.com/cskai4g/mypageloader/ (string)
        ,callback: jsonCallback (string)
        ,items: [
            {
                content: 
<html>
<head>
/** <後略> **/ 

あとは、コールバック関数内で、items[0].contentに格納されたHTMLを好きなように使える。

PipesBrowser.html
<html>
    <head>
        <script type="text/javascript">


const BASE_URL = 'http://pipes.yahoo.com/cskai4g/mypageloader?url=';
const OPTIONS =  '&_render=json&_callback=jsonCallback';

/**
 * テキストボックスに入力されたURLをYahoo!Pipes経由で取得
 */
function browse() {
    var url = document.getElementById('url').value;
    var newScript = document.createElement('script');
    newScript.charset = 'utf-8';
    newScript.src = BASE_URL + encodeURIComponent(url) + OPTIONS;
    document.body.appendChild(newScript);
}

/**
 * PipesからJSON取得時のコールバック関数
 * 取得したJSON(HTML)を表示する。
 */ 
function jsonCallback(data){
    var item = data.value.items[0];
    var newHtml = item == null ? '取得できませんでした。' : item.content;
    document.getElementById('new_html').innerHTML = newHtml;
}


        </script>
    </head>
    <body>
        <input id="url" type="text" size="100" 
               value="http://d.hatena.ne.jp/fuzzhead/" />
        <input type="submit" value="Go" onclick="browse()" />
        <hr />
        <div id="new_html"/>
    </body>
</html>

実行結果

実行前


てきとうなURLを入力して、ボタンを押す。

実行後


こんなかんじで表示される。
もちろんクライアント側からは、対象URL(はてな)にはアクセスしていない。

おしまい

Yahoo!Pipesでセンサーシップに対抗できますよ、という話でした。

*1:モジュールをひとつ削っただけだけど