Hatena::ブログ(Diary)

SO NOTE そうのて (;^ω^) このページをアンテナに追加 RSSフィード Twitter

2009.03.07

Yahoo!知恵袋の回答一覧ページや質問一覧ページに、その質問の評価ポイントをプラスするグリモン

【追記】2009.03.09 一部不具合があったので、修正してます。

before

f:id:so_blue:20090308003520p:image

After

f:id:so_blue:20090308003522p:image

説明

このグリモンをインストールすると、回答(質問)一覧ページに、その回答(質問)の評価ポイントが追加表示されます。少しわかりにくいですが、右端の回答数の左横に y / x って表示されてる数字がそれで、xがその質問や回答を評価した人の人数、yがそのうちで役に立ったと評価した人の人数となります。この数字はベストアンサーの下にある

f:id:so_blue:20090303115127p:image

の数字です。で、その質問のベストアンサーが自分だった場合、

f:id:so_blue:20090308003523p:image

な感じでピンクに表示されます。

先日、何気に自分の回答したページを見てみたところ、役に立ったって評価されてたんで、じゃあついでに他のも…と確認してたんですが、個々の回答の評価ポイントを確認するには、現状のページ構成だと回答一覧ページからいちいち質問ページそのものに飛ばないと確認出来ず、めんどくさいなーと思い、グリモンの勉強がてら作ってみました。

ちなみに、自分の回答を役に立ったって評価してくれた人の割合は半分以下でした。。。(;谷)

ソース

// ==UserScript==
// @name           chiebukuroUsefulPointGetter
// @namespace      http://d.hatena.ne.jp/so_blue/
// @include        http://my.chiebukuro.yahoo.co.jp/my/myspace_ansdetail.php*
// @include        http://my.chiebukuro.yahoo.co.jp/my/myspace_quedetail.php*
// ==/UserScript==
(function(){

	//公開idの取得
	var oid = document.getElementsByClassName('yjmthloginarea')[1].getElementsByTagName('B')[0].textContent;
	//解決済みの行だけ取得
	var xpath = '/descendant::img[@alt=\'\u89e3\u6c7a\u6e08\u307f\']';
	//正規表現を作る
	var re = new RegExp('\\d+', 'ig');
	
	var func = function(docs) {
		var r = document.evaluate(xpath, docs[0], null, 7, null);
		for (var i = r.snapshotLength - 20, len = r.snapshotLength; i < len; i++) {
			var node = r.snapshotItem(i);
			var sURL = node.parentNode.getElementsByTagName('A')[0].href.split('\*-')[1];
			GM_xmlhttpRequest({
				method: 'GET',
				url: sURL,
				onload: addUsefulPointElement(node)
			});
		}
	}

	func([document]);
	if (window.AutoPagerize) window.AutoPagerize.addFilter(func);

	//評価ポイントの要素を追加する
	function addUsefulPointElement(elm) {
		return function(res) {
			var x = document.createElement('DIV');
			x.innerHTML = res.responseText;
			//評価ポイント要素の取得
			var u = x.getElementsByClassName('useful')[0];
			if (!u) { x = null; return; }
			
			//評価ポイントを y / x 表示にする
			var txt = u.getElementsByTagName('P')[0].textContent;
			var s = txt.split('\u4eba\u4e2d');
			var s1 = s[0].match(re).join(''); var s2 = s[1].match(re).join('');
			s = s2 + ' / ' + s1;
			var elmSPAN = document.createElement('SPAN');
			elmSPAN.setAttribute('style', 'border: solid 1px #ccc; width: 5em; display: inline-block; text-align: center; font-size: small; -moz-border-radius: 5px; margin-left: 10px; padding: 2px;');
			//ベストアンサーが自分かどうかを判定して、自分の場合は
			//背景色をピンクに変える
			var baid = x.getElementsByClassName('bestAnswer Extends-details')[0].getElementsByTagName('EM')[0].textContent;
			if (baid == oid) elmSPAN.style.backgroundColor = 'pink';
			elmSPAN.textContent = s;
			elm.parentNode.parentNode.getElementsByTagName('DIV')[0].appendChild(elmSPAN);
		}
	}

})();

参考にしたページ

グリモンをAutoPagerizeに対応させる方法については、

勝手に添削してみる (AutoPagerize対応GMScriptの書き方みたいな) - FFFF - 0x

を参考にさせてもらいました。ってか、addFilterんとこはまんまコピペさせてもらいました。(;^ω^)

もう少しなんとかしたいなと思ってる部分

継ぎ足された要素だけを取得する方法が結局よくわからなかったので、知恵袋の回答(質問)ページ構成が1ページに20行表示されてる事から、XPathで取得した要素の集合の後ろから20個を処理する様にしてる部分。1ページ辺りの表示数が変わると重複して処理されたり、処理されない行が出てくる。あと、XPathで返される要素集合の順序が必ず同じなの?って部分。他にもあるけど、特に気になってるのはこの2点。

とはいえ

一応は動いてるので(;^ω^)、よければどうぞ

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/so_blue/20090307/1236444946
Connection: close