日ごろゴリゴリとプログラムを書くような習慣がない、なんちゃってエンジニア風何でも屋なので、すぐにどうやっていたのかを忘れてしまいがち(年齢のせいかもしれないが…)。ということで、あっさり解決はしたんですが、javascriptでのDOM操作、getElementsByを続けて操作する方法、つまり階層の中身を取得する手順を記しておきたいと思います。忘れっぽい人には参考になるかも?(自分に言い聞かせてる気もする)
今回はゲーム発売日とタイトルを取得
サンプルとして、実際に結果が見られる方が実感しやすいと思うので、ファミ通.comさんの過去に発売されたソフトのページからゲームの発売日とタイトルを取得していきたいと思います。
解析用にページのソースを表示
目的のページにたどり着いたら、解析用にページのソースを表示させておきます。ざっと調べてみると、発売日ごとの大枠はitemBlockWrapというクラス名で、個々のタイトルはitemNameのクラス名で取得ができそうです。
まずは大枠の階層を取得(発売日)
var a = document.getElementsByClassName('itemBlockWrap');
これによって、aには発売日ごとのデータが収まっている状態になっています。ここから日付を取り出すにはheading03innerのクラス名を指定してあげればよさそうです。
ということで、以下のように書いてみたんですが、これではうまく取得できません。
var yyyymmdd = a.getelementsByClassName('heading03inner')
aの中身は複数あるので、どの部分のheading03innerを取り出せばいいのかわからない状態という感じでしょうか。逆にいえば、それを指定してあげれば、ちゃんと取得できるようになるはずです。ここでは[0]をつけて、最初に出てくる日付を取り出してみましょう。
var a = document.getElementsByClassName('itemBlockWrap'); var yyyymmdd = a[0].getElementsByClassName('heading03inner'); console.log(yyyymmdd[0].innerText);
上記のコードをコンソールにコピペして実行してみると
ちゃんと取得できてますね。yyyymmddの部分も[0]を付けて処理しています。指定してあげないと取得できないので注意しましょう。
大枠の中身を取得していく(タイトル名)
続いてはタイトル名を取得していきます。個々のタイトルはitemNameのクラス名でしたね。
var gametitle = a[0].getElementsByClassName('itemName');
ちゃんと[0]でしてあげておきます。ただ、同じ発売日に複数のタイトルがあることが普通なので、gametitleには複数の情報が入っている状態になっていると予測できます。なので、取り出すためにはfor文などを使い、ひとつずつ取り出してあげる必要がありそうです。
for (var t=0; t<gametitle.length; t++) { console.log(gametitle[t].innerText); }
上のような感じでしょうか。今までのコードと組み合わせてみると以下のようになります。これを実行してみると
var a = document.getElementsByClassName('itemBlockWrap'); var yyyymmdd = a[0].getElementsByClassName('heading03inner'); console.log(yyyymmdd[0].innerText); var gametitle = a[0].getElementsByClassName('itemName'); for (var t=0; t<gametitle.length; t++) { console.log(gametitle[t].innerText); }
いい感じで取得できましたね。
大枠に戻って他の日付も取得するように改造する
最後の仕上げは複数の日付に対応させる部分になります。これも先ほど出てきたfor文での処理でいけます。さらにyyyymmddの[0]とinnerTextも一文にして処理してしまいましょう。こういう書き方もできたりしますよ。
for (var i=0; i<a.length; i++) { var yyyymmdd = a[i].getElementsByClassName(heading03inner)[0].innerText; }
これで日付の対応もできたので、コードに上の部分を組み込んで調整してみます。
var a = document.getElementsByClassName('itemBlockWrap'); for (var i=0; i<a.length; i++) { var yyyymmdd = a[i].getElementsByClassName('heading03inner')[0].innerText; console.log(yyyymmdd); var gametitle = a[i].getElementsByClassName('itemName'); for (var t=0; t<gametitle.length; t++) { console.log(gametitle[t].innerText); } }
結果はこうなりました!
ちゃんと複数の日付に対応できました。ついでにブックマークレット化してみましょう。
コンソール出力をテキスト成形に修正
そんなに複雑なことじゃないので、コードを載せちゃいますね。入れ物はoutputにしました。
var output = ""; var a = document.getElementsByClassName('itemBlockWrap'); for (var i=0; i<a.length; i++) { var yyyymmdd = a[i].getElementsByClassName('heading03inner')[0].innerText; output += yyyymmdd + ":\n" ; var gametitle = a[i].getElementsByClassName('itemName'); for (var t=0; t<gametitle.length; t++) { output += gametitle[t].innerText + "\n"; } }
別タブ(ウインドウ)を開いて結果を表示させる
以前、F1の公式サイトスクレイピングから別タブ部分を引っ張ってきました。
var d=window.open().document; d.writeln('<textarea rows=25 cols=100>'+output+'</textarea>');
これを組み合わせて、さらにブックマークレット用に最初の部分と〆の括弧を追加します。
javascript:(function(){ var output = ""; var a = document.getElementsByClassName('itemBlockWrap'); for (var i=0; i<a.length; i++) { var yyyymmdd = a[i].getElementsByClassName('heading03inner')[0].innerText; output += yyyymmdd + ":\n" ; var gametitle = a[i].getElementsByClassName('itemName'); for (var t=0; t<gametitle.length; t++) { output += gametitle[t].innerText + "\n"; } } var d=window.open().document; d.writeln('<textarea rows=25 cols=100>'+output+'</textarea>'); };
ブックマークレット化
上のコードをブックマークレット用にスペースや改行コードを取り除きます。。。これをさくっと変換してくれる便利なサイトがあったりするので、活用するのも手ですね(下のサイトを利用する際は上記のブックマークレット用に追加した最初の部分と〆の括弧は自動で付けてくれるので不要です)。
WDF – Software : ブックマークレット作成スクリプト
実際に完成したスクリプトは以下になります。
javascript:(function(){var output = "";var a = document.getElementsByClassName('itemBlockWrap');for (var i=0; i<a.length; i++) {var yyyymmdd = a[i].getElementsByClassName('heading03inner')[0].innerText;output += yyyymmdd + ":\n" ;var gametitle = a[i].getElementsByClassName('itemName');for (var t=0; t<gametitle.length; t++) {output += gametitle[t].innerText + "\n";}}var d=window.open().document;d.writeln('<textarea rows=25 cols=100>'+output+'</textarea>');})();
ブックマークレットの登録の仕方は以下の記事を参照してください。
登録したブックマークレットを実行すると…
無事、別タブが開いて結果を表示することができました。
まとめ
なんだかんだでブックマークレットまで作成しましたが、ホントすぐにやり方とかド忘れしてしまうんですよね。。。さて、前回のF1の時とはちがって、階層の中身をさらにDOM操作するという流れになりました。まず、どの部分なのかを指定することを忘れないようにすればちゃんと取得できますね。今回でいう[0]や[i]の部分。そこを押さえておけば、階層深くのものでも狙い通り取得できます。jQueryを使わないっていう流れもあったりしますので、javascriptでの基本的なやり方を確認しておくのもいいかもしれません。参考になれば幸いです!