うーん。早くこのマニアックなBlogからは卒業したいな…(;^ω^)
久しく時間が空いちゃいましたがYahoo!Pipes講座を再開します(・∀・)!過去の講座は以下を参考にして下さい。今回は9回目。iTunesからスクショを引っこ抜く部分です!
- [Pipes] Yahoo! Pipesを勉強したい方へ
- [Pipes] 講座01(FetchFeed、Sort)
- [Pipes] 講座02(Text/URLInput、Yahoo!Search、Filter、Regex)
- [Pipes] 講座03(String/URLBuilder、FetchData、Rename)
- [Pipes] 講座04(MyPipe、Union、Unique)
- [Pipes] 講座05(ItemBuilder)
- [Pipes] 講座06(Loop)
- [Pipes] 講座07(Dapperの使い方)
- [Pipes] 講座08(Dapper情報の取得、FetchPage)
スクショの引っこ抜き方ですが、Dapper経由にした方が簡単なのでは?と最初は思っていたんですけど、iTunes情報のスクショって画像のURLだけ分かっても片手落ちだったんです。縦なのか横なのか?その情報はIMGタグのclass属性に記載されてます…。
つまりHTMLタグをまんま抜き出せないとダメ。Dapperはタグの属性は抽出できません。ということで、講座09ではFetchPageを使ってYahoo!Pipesのみでスクショを取得する方法をご紹介します。スクショなら文字化けの心配は無いですしヽ(´ー`)ノ
長らく空いたので全体像を示してみる…
このPipes講座は、AppHtml(旧バージョン)をどうやって作ったのか、順番に説明しつつPipesの理解を深めるという意味合いで連載してます。各連載で作ったPipeがどう繋がっているのが、全体像が欲しいという声もあったので先に明示しときます。
講座は全12回。どの講座がどういった役割でAppHtmlの構成要素になっているかを図で表現してみました。これまで作ってきた講座のOutputをうまく組み合わせることでAppHtmlが完成する訳です。そんな中で今日は講座09をご説明しますヽ(´ー`)ノ
iTunesのスクショのHTMLを分析する
引っこ抜く対象であるiTunesの情報(HTMLソース)を見てみます。
ソースは長いんですがスクショの部分は上記です。探し方はChromeならば右クリメニューに入ってる「要素の検証」FirefoxならばFirebugのAddonを使っての「要素の調査」で該当箇所を探します。このソースから分かったことは以下の点。
- 決まったタグ構成でスクショ部分は表現されてる
- iPhoneで最大5枚、iPadで最大5枚のスクショが登録されてる
- DIVタグ「metrics-loc」属性でiPhone用かiPad用か分かる ※注意!!
- iPhoneスクショ群とiPadスクショ群の間にはDIVタグ終了が連なる
- 各スクショの前には必ずDIVタグ「class=”lockup”」が入ってる
- iPhone用のスクショのIMGタグには「alt=”iPhone….”」が入ってる
- iPad用のスクショのIMGタグには「alt=”iPad….”」が入ってる
- スクショが縦ならばIMGタグには「class=”portrait”」が入ってる
- スクショが横ならばIMGタグには「class=”landscape”」が入ってる
ということでこの法則性を使って(10枚でも良かったけど)最大5枚のスクショを取得していこうと思います。ここで注意点ですが、上記の「metrics-loc」属性ですが、最近のiTunesウェブから登場した属性みたいで、昔のはついてないみたい。
ここ最近iTunesウェブが段階的に変更されていて決め打ちのマッシュアップは危ないということを痛感しました。なので古いほうも新しい方も同じルールになってる部分だけ使ってスクショを抜き出そうと思います!
具体的には青字の法則を使ってPipeでスクショを抜き出していきます。
講座09で作るPipeのゴール
iTunesのURLと画像サイズを入れるとスクショのセットを返すPipeを作ります。画像サイズの指定はiPhoneの縦スクショのサイズを指定し、横スクショはPipe内で計算。又、iPadスクショはiPhoneスクショとの大きさの比率を指定するようにしました。
- 「url」iTunesのURL
- 「imagesize」iPhoneの縦スクショのサイズ(px)
- 「ipadrate」iPadスクショのiPhoneスクショと比較した場合の比率
Pipe実行後の結果は、Pipeのデバッガーに「image1」から最大で「image5」までのスクショタグをセットするところまでとします。
実は、アプリによってはスクショが1枚しか無いものも存在します。その場合には「image1」だけセットされて「image2」から「image5」までは何もセットされない。つまり空。このようにしたいと思います。
1回の取得で5枚?5回の取得で5枚?
この部分、実は概念的な部分なんですけど、超重要なのでしっかりと説明しておきます。Pipeは複数件の結果が返ってきた場合、結果も複数件になります。でも、今回は1回の取得で結果を「image1」から「image5」にセット、1件の結果として返したいのです。
そんなことできんのか?
できるんです!
その為に今回は2つのPipeを組み合わせて結果を取得するようにしました。
子供のPipeでスクショを複数件取ってくる。で、親のPipeで、子供の結果を「image1」から「image5」までにセットする。もし子供の結果が3件だった場合「image4」と「image5」はセットされますが空がセットされるので、結果的に「image1」から「image3」までの結果が1回で返ります。具体的に作ってみましょう!
最初に子供のPipeから作ってみる
子供のPipeは「講座09-sub」という名前にしました。子供のPipeは親から以下の値を引き継ぎ、結果を返します。結果はスクショの枚数分の件数を返します。
- 「url」iTunesのURL
- 「iPhonePortrait」iPhoneの縦スクショのサイズ(px)
- 「iPhoneLandscape」iPhoneの横スクショのサイズ(px)
- 「iPadPortrait」iPadの縦スクショのサイズ(px)
- 「iPadLandscape」iPadの横スクショのサイズ(px)
完成した子供のPipeは以下の通り。
手順1(URLInput、FetchPage)
入力値であるiTunesのサイトを見にいって特定条件でソースの一部分を取得。更にdelimiter(区切文字)を設定して繰り返しのHTMLを複数の結果に分割します。
ライブラリから「URL Input」と「Fetch Page」を選択し、配置します。
「url」にはiTunesのURLが入ります。デバッグしながら進めたいのでTextforceのURL「http://itunes.apple.com/jp/app/textforce-dropbox-text-editing/id396444947/?mt=8」をDebug欄に入力します。
Fetch Pageですが、ここでiTunesスクショのHTMLの法則をそのまんま指定していきます。URLには先のURLInputで入力した値を連結。Cut content fromには「<div class=”lockup”>」を指定。この条件に最初にヒットした場所から、toに指定する「</div></div>」までのHTMLソースを抜き出します。
この時点でデバッグを見てみると分かるのですが、5枚のスクショのHTMLがひとつのitem.contentの中に入ってるはず。この5枚を5つのデータに分解するのがdelimiterの設定になります。「<div class=”lockup”>」を指定するとこのキーワードが登場する度にデータを分割してくれます。結果は以下のようになるはず。
上記を見て分かることは、ひとつのHTMLソースが5件のデータに分割されたってこと。分割された個々のitem.contentを見ると上から順番にスクショが収まってます。
手順2(NumberInput、StringBuilder)
次にスクショのIMGタグをいじって画像サイズ(width属性)を指定する為の準備をしておきます。画像には4種(iPhone縦、iPhone横、iPad縦、iPad横)があるのでそれぞれのwidthタグを作ります。手順1のデバッグ内容でalt属性があり、そこでiPhoneなのかiPadなのか分かります。更にその後にclass属性があり、縦か横かが分かります。
- alt属性でiPhoneなのかiPadなのかが分かる
- class属性で縦なのか横なのか分かる
IMGタグにwidthも加えた値をセットする為、NumberInputで指定された数字とStringBuilderを使って予め文字列を作っておきます。
ライブラリから「Number Input」と「String Builder」を選択し、配置します。
これがひとつ目。iPhone縦の時の文字列は「alt=”iPhone” class=”portrait” width=”」+ NumberInputの値 +「”」になります。
これがふたつ目。iPhone横の時の文字列は「alt=”iPhone” class=”landscape” width=”」+ NumberInputの値 +「”」になります。
同様にiPad用の縦と横も同じように作ります。
iPad縦の時の文字列は「alt=”iPad” class=”portrait” width=”」+ NumberInputの値 +「”」になります。iPad横の時の文字列は「alt=”iPad” class=”landscape” width=”」+ NumberInputの値 +「”」になります。これで準備終わり。
手順3(Regex)
いよいよ仕上げ。手順2の準備は、ここで使われます。
ライブラリから「Regex」を選択し、配置します。
手順1のFetchPageをRegexに連結。alt属性をシンプルに置換。その後、alt属性とclass属性の組み合わせによって手順2で作っておいた値と置換。結果、サイズ指定の入った個別のHTMLが完成しました。
尚、今回、Regexで新たな表現を使ってます。
「”iPhone.*?”」という表現。「?」があるか無いかで結果が変わってきます。通常「.*”」とした場合、該当文字列の最後に登場する「”」がヒットしてしまいます。つまりalt属性だけでなく、class属性も含めて変換されてしまうのです。しかし「?”」とした場合には、最初に現れる「”」がヒット、つまりalt属性だけの変換が実現するのです。
結果は以下の通り。
シンプルになったalt属性にclass属性が付き、最後にwidth属性が追加されました。
親のPipeの中で子供のPipeを呼ぶ
かなり長いエントリーになってきた…。ちょっと飛ばし気味で説明します。完成した親のPipeは「講座09」という名前にしました。結果はこちら。
手順4(URLInput、ItemBuilder)
入力値であるURLをitemに変換し、スクショを取得する直前の状態にします。
ライブラリから「URL Input」「Item Builder」を選択し、配置します。
ここまでは難しい部分は無く、入力値がitem.urlになっただけ。だがしかし、今回は意図的にItemBuilderを使いました。ここに深い意味があるのです。手順6で説明します。
手順5(NumberInput、SimpleMath)
子供のPipeを呼ぶ前に、子供のPipeに渡す値を準備します。入力値はiPhone縦サイズのpxとiPadスクショにした場合の比率。これらの2つの値から以下の4パターンのwidth値を作成します。前提としてスクショの縦横比率は2:3。この法則を使います。
- 「iPhone縦幅」=「iPhone縦サイズ」
- 「iPhone横幅」=(「iPhone縦サイズ」÷2)×3
- 「iPad縦幅」=「iPhone縦サイズ」×「iPad比率」
- 「iPad横幅」=((「iPhone縦サイズ」×「iPad比率」)÷2)×3
ライブラリから「Number Input」「Simple Math」を選択し、配置します。
作らなければならないのは「iPhone縦幅」意外の3つ。NumberInputの値に対し、SimpleMathのモジュールは単純に四則演算をしてくれるんです。上記は左から順に「iPhone横幅」「iPad縦幅」「iPad横幅」を計算してます。
手順6(Loop、MyPipes、Rename)
いよいよ子供のモジュールをLoopで呼んで親にマッピングしていきます。先ほど手順4でわざわざItemBuilderを作ったのは、Loopがスタートモジュールとして使えないから…。Loopはベースとなるメインの流れがあった中でしか使えないという制約があるのです。
ということで今回は強引にItemBuilderでメインの流れを作り、そのメインの流れにLoopで子供のPipeの結果をぶら下げてimage1からimage5を作っていくようにしました。
ライブラリから「Loop」「子供のPipe」「Rename」を選択し、配置します。
子供のPipeに渡す値は、手順4と手順5で作った値を使います。urlには「item.url」をセットし、その他の値は手順5の結果と紐付けます。結果は「assign – all」でitem.loopの直下に全件取ってくるように設定しました。
デバッガーでRenameする前の状態は上記な感じ。urlと同じレベルにloopがあり、その下に0から4までのスクショが並んでます。これでOK。
この状態でRenameでurlと同じレベルにloopの下の値を移動します。上記のRenameモジュールの通りに設定してみて下さい。
デバッガーでRenameした後の状態は上記な感じ。urlと同じレベルにimage1からimage5までが並びます。これがやりたかったこと。もしLoopの下にスクショが3枚しか無かったとしたら、自動的にimage4とimage5は空になるのでitemから消えます。
手順7(Regex)
締めはitem.loopを空にするだけ。ライブラリから「Regex」を選択し、配置します。
ここはいつもの通り。以上で講座09のPipeは完成です。お疲れ様です。
あとがき…
今回は概念的に今までで一番難しかったかも…。Pipeのテクニックも必要なんですが、どうやって元サイトの法則を把握し、それをPipeで取ってくるように表現するか。やりごたえがあったんじゃないかなぁと。ここで、次回の予告をしておきます。
次回の講座10は、講座09が理解できてればPipe自体は簡単です。アイコンを取ってくるPipeを作ります。講座09の理解度を試す意味で、次回までに挑戦してみて下さい!
一応、答えを紹介しときます。
尚、講座10では、その他のトピックとして、これまで使ってきた「Regex」の中の正規表現をまとめておこうと思ってます。乞うご期待!
全般を通じて、こうやって欲しいとか要望があればTwitterやコメントにてご指摘下さい。今後のカリキュラムですが、以下の構成で進めていきます。
講座01(FetchFeed、Sort)講座02(Text/URLInput、Yahoo!Search、Filter、Regex)講座03(String/URLBuilder、FetchData、Rename)講座04(MyPipe、Union、Unique)講座05(ItemBuilder)講座06(Loop)講座07(Dapperの使い方)講座08(Dapper情報の取得、FetchPage)講座09(NumberInput、SimpleMath)←今ココ- 講座10(良く使う正規表現まとめ)
- 講座11(MyPipeの可読性の向上)
- 講座12(Javascriptとの連携)
いよいよ残すは3回。今回の講座09を乗り切ればゴールは近し!ですヽ(´ー`)ノ
-
タグ: Bookmarklet, Dapper, Google, hiroスタイル, Yahoo!Pipes
何時もご参考にさせて頂いています。
pipeで質問があります。簡単なpipeしか作れないのでですが[Fetch FeeD]-[Pipe Out]なのですが、取得した結果からimageタグ等の特定のタグかたまりを排除する方法は有るのでしょうか?
宜しくご教授願います。
以上