読者です 読者をやめる 読者になる 読者になる
スポンサーリンク

Youtubeの動画playlistのリンク集を,Firebugワンライナーで生成しよう(consoleからXPATHでスクレイピング)

ブラウザ javascript XML 動画

Firebugのコンソールを使って,Webページの情報を加工してみよう。

  • HTMLの中から,特定のclassを持ったDOM要素だけを抽出

という処理をしてみる。


こういう単一ページ内でのWebスクレイピングは,簡易なブックマークレットでも可能。


だが,もしfirefoxを使っているなら,デバッグ用コンソールを利用すると一層便利だ。コンソール用のAPIメソッドを使えるから。

XPathの勉強だと思って,やり方を覚えてみよう。

題材となるプレイリストのページ


Webページの題材としては,「Youtubeのプレイリスト一覧画面」をネタにする。

このページ内から,全ての動画への個別のハイパーリンクを抜き出して,加工したい。


例えば,こんなプレイリストがある:

YakuSu ウクライナ語講座 さんのアップロード動画 - YouTube
http://www.youtube.com/playlist?list=...

これはウクライナ語の入門ビデオのリストだ。

個々のビデオのURLをリストアップして,番号付きの箇条書きにして,ブログに貼り付けたいとする。

つまり,「ムービーのリンク集を一発で生成したい」のだ。


手作業でいちいち右クリックしてURLをコピーするのは,数が増えるとめんどい。

あなたなら,どういう方法を使うか?

Firebugのコンソールを使おう

下記のコードを,Firebugのコンソールにペーストしてみよう。

1行だけで済む。

console.clear(); $x('//a[contains(concat(" ",normalize-space(@class)," "), " pl-video-title-link ")]').forEach(function(elem, i){ console.log((i+1)+". "+elem.innerHTML.replace(/^\s+/,"").replace(/\s+$/,"")+"\n"+elem.href+"\n\n\n");}); "";

Youtubeのプレイリスト一覧画面を開いた状態で,これを実行すると,コンソールで下記のようなテキストが出力される。

1. 四季と月の名前 - YakuSuウクライナ語講座
http://www.youtube.com/watch?v=zKIU-W...


2. I love you - ウクライナ語で告白 - YakuSuウクライナ語講座
http://www.youtube.com/watch?v=usucSs...


3. すみません - ウクライナ語で謝罪 - YakuSuウクライナ語講座
http://www.youtube.com/watch?v=a8X9sD...


4. ありがとう - ウクライナ語で感謝 - YakuSuウクライナ語講座
http://www.youtube.com/watch?v=2SmgPr...


5. こんにちは - ウクライナ語で挨拶 - YakuSuウクライナ語講座
http://www.youtube.com/watch?v=6woiPj...

ブログに貼り付ければ,すぐリンク集になる。なんと簡単なスクレイピング。


以下はコードの解説。

改行を含めて整形したコードは下記のようになる。

console.clear(); // 出力をクリア

$x('//a[contains(concat(" ",normalize-space(@class)," "), " pl-video-title-link ")]') // XPathでタグを絞り込み
  .forEach(function(elem, i){ // 全要素をループ
    console.log(
      (i + 1) + ". " 
      + elem.innerHTML.replace(/^\s+/,"").replace(/\s+$/,"") // 先頭と末尾の空白をトリム
      + "\n" + elem.href + "\n\n\n"
    );
  });
""; // 末尾に「undefined」と出力されるのが気持ち悪いので。

ブックマークレットのようにお気に入り操作をしなくても,すぐに実行できるというのが長所。

他の形式

Youtube上でプレイリストになっていない場合は,

「アップロードされた動画」の一覧画面で下記のコードを実行すれば似たような結果を取得できる。

console.clear(); $x('//a[contains(concat(" ",normalize-space(@class)," "), " yt-uix-tile-link ")]').reverse().forEach(function(elem, i){ console.log(elem.title+"\n"+elem.href+"\n\n\n");}); "";

Firebug上でXPATH抽出結果に対するreverse()が効かない場合は,下記のように改変。

console.clear(); 
var arr_movies = [];
$x('//a[contains(concat(" ",normalize-space(@class)," "), " yt-uix-tile-link ")]')
.forEach(function(elem, i){ 
 arr_movies.push(elem);
});
arr_movies.reverse().forEach(function(elem,i){        
 console.log(elem.title+"\n"+elem.href+"\n\n\n");
}); "";


「あとで見る」リストから抽出することもできる。

console.clear(); $x('//a[contains(concat(" ",normalize-space(@class)," "), " pl-video-title-link ")]').forEach(function(elem, i){ console.log(elem.innerHTML.replace(/^\s+/,"").replace(/\s+$/,"")+"\n"+elem.href+"\n\n\n");}); "";

「履歴」とか「高く評価した動画」からリストを抽出することもできる。

console.clear(); 
var arr_movies = [];
$x('//a[contains(concat(" ",normalize-space(@class)," "), " yt-uix-tile-link ")]')
.forEach(function(elem, i){ 
 arr_movies.push(elem);
});
arr_movies.reverse().forEach(function(elem,i){        
 var tit = elem.textContent
   .replace(/^[ | |\t|\n]+/g,"")
   .replace(/[ | |\t|\n]+$/g,"")
 ;
 console.log(tit+"\n"+elem.href+"\n\n\n");
}); "";


「ひまわり動画」なら下記のコードでOK。

console.clear(); $x('//h2[@class="force_title"]//a').forEach(function(elem, i){ console.log((i+1)+". "+elem.innerHTML.replace(/^\s+/,"").replace(/\s+$/,"")+"\n"+elem.href+"\n\n\n");}); ""; 

参考リンク

XPathとFirebug APIについて:

特定のclass属性を持った任意の要素にマッチするXPath | 3.14
http://white.s151.xrea.com/blog/2008-...

  • div[contains(concat(" ",normalize-space(@class)," "), " hoge ")]


Firebugで,XPathを使って特定のclass名を指定し,DOM要素を絞り込む方法
http://computer-technology.hateblo.jp/entry/20140312/p2

  • $x("//div[@class='hoge']")


JavaScript初級者から中級者になろう:十章第二回 DOMでのXPathの利用
http://uhyohyohyo.sakura.ne.jp/javasc...

  • documentのevaluateというメソッドは、5個の引数を渡してXPathを処理してもらい、結果をXPathResultというオブジェクトで返す


Firebug Command Line APIを弄る($xのコンテキスト) - os0x.blog
http://os0x.hatenablog.com/entry/2007...

  • $x.toSource() と打ちます。 すると、 (function (xpath) {return FBL.getElementsByXPath(baseWindow.document, xpath);})


効率的なデバッグをサポートするFirebugのコンソールAPI - builder by ZDNet Japan
http://builder.japan.zdnet.com/html-c...

  • FirebugのコンソールAPIを使えば、コンソールへのメッセージの出力やスクリプトの実行時間の計測などを行うことができる。


Command Line API - FirebugWiki
https://getfirebug.com/wiki/index.php...

  • $x(xpath) Returns an array of elements that match the given XPath expression.


Firebugの便利な組み込み関数 - 技術メモ帳
http://d.hatena.ne.jp/lurker/20060801...

  • Firebugには、便利な組み込み関数が定義されている。$x() で 任意のXPath要素が取得できる

JavaScriptで配列をループで処理するベストな書き方は? - QA@IT
http://qa.atmarkit.co.jp/q/2803

  • JavaScriptで配列をループを使って処理する場合、 for...inまたはネイティブのArray.forEach()

$x()で取得した要素配列は,[0]のように配列インデックスを使って個別の要素を取り出し,DOM要素として操作できる。

want to get an innerHTML through xpath - Google グループ
https://groups.google.com/forum/#!top...

  • $x("//div[@id='searchtextPanel_wrap']/div[4]/div[4]")[0].innerHTML;

末尾のundefined問題などについて:

JavaScript - forEachとforとforinの速度テスト - Qiita
http://qiita.com/toshirot/items/94d13...

  • forEach(function (x, i))


正規表現 - JavaScript | MDN
https://developer.mozilla.org/ja/docs...

  • \s : スペース、タブ、改ページ、改行を含む 1 つのホワイトスペース文字にマッチします。


Issue 3820 - fbug - console.log always appends a line saying undefined - Web development evolved - Google Project Hosting
https://code.google.com/p/fbug/issues...

  • I expect that only "Hello, World!" to be printed, instead I see this: "Hello, World!" undefined


Issue 3784 - fbug - "undefined" shouldn't be shown as return value of internal function calls in Console Panel - Web development evolved - Google Project Hosting
https://code.google.com/p/fbug/issues...

  • function change() { test = "hello"; } change(); >hello :Better if not perfect

関連する記事:

Selenium 中級者になろう (変数+XPath+JavaScriptを,テストケース中で利用する方法)
http://language-and-engineering.hatenablog.jp/entry/20090818/p1


タブブラウザで,「開いている大量のタブ」をテキストで保存し,復元する方法
http://language-and-engineering.hatenablog.jp/entry/20140123/p1


はてなダイアリーに執筆した記事一覧を,表形式に整理するブックマークレット (アーカイブページを,Excelに貼り付けやすく整形加工)
http://language-and-engineering.hatenablog.jp/entry/20140102/p1


はてブのマイページから,情報を一括して整形・抽出するブックマークレット
http://language-and-engineering.hatenablog.jp/entry/20131229/p1