Table of Contents

Research Artisan Lite Edit

Research Artisan Liteを使用している。phpを更新後,「アクセス解析設定」に入ろうとするとphpのエラー通知(Exception caught)が出た。

Declaration of AdminHelper::pageTag() should be compatible with BaseHelper::pageTag($pageCount)

対処

ra/.htaccess

に以下の記述を追加。

php_value error_reporting 0

アクセス制限 Edit

自宅サーバーを立てるだけなら固定IPは不要で,ダイナミックDNSでもよい。しかし外部にあるサーバーの認証に自宅IPを使う場合は,ダイナミックIPだとちょっと不便だ。逆引きできないからである。(.htaccessに,ダイナミックDNSのホスト名を書いてもworkしない。Cf. HostnameLookups

幾つかの対処策はあるが,一つ,ホスト名とクッキーを併用して認証するのは割と簡単だ。

まず,クッキーを発行するCGIを用意する。次に,アクセス制限したいディレクトリの.htaccessで条件を記述する。

  • クッキー発行CGI (Perl)。このURLは人に知られてはいけないし,アクセスに制限を付ける。
    my $expires;
    {
    	local $expire_delta_hour = 24*7;
    	local(@t, @m, @w);
    	@t = gmtime(time() + $expire_delta_hour*60*60);
    	@m = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
    	@w = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
    	$expires = sprintf(" expires=%s, %02d-%s-%04d %02d:%02d:%02d GMT;",$w[$t[6]], $t[3], $m[$t[4]], $t[5]+1900, $t[2], $t[1], $t[0]);
    }
    print <<END;
    Set-Cookie: xxx=xxxxxxxxxxxx; $expires; path=/;
    Content-type: text/html;charset=UTF-8
    
    <HTML>
    
  • .htaccess
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
    Allow from .ap.plala.or.jp
    
    RewriteEngine on
    RewriteCond %{HTTP_COOKIE} !xxx=xxxxxxxxxxxx
    RewriteRule ^ - [R=404,L]
    

第三者クッキー Edit

普段は第三者クッキーを拒否しているが,ANAマイレージモールの類で買い物をする際など,念のため有効にしたいことがある。ブラウザーの設定を開けば確認は簡単だが,さらに簡単に確認するのに,はてなブログとサードパーティCookie - ヘルプ - はてなブログというページを使っている。このページを開くだけで確認できる。上部に何も表示されなければ第三者クッキーは有効。

  • hatena_help_cookie.png

ちなみに,第三者クッキーが無効だと,JALの場合は,会員番号入力画面に行く前に注意が出て,それ以上進めない。ANAでは特に何も起きない。

被引用 Edit

Impress Watchの記事には被引用のリンク(記事Aが出た後に,記事BがAを引用したなら,AにBへのリンクが自動的に追加されること)がないので不便。記事Aをリンクやブックマークから開いた際(既に内容が古くなっている可能性が高い),その最新の動向をぱっと知りたくても,それができない。(Aより古い記事CへのリンクならAにあるが,Aより未来方向へのリンクはない。)記事検索を使う必要がある。(しかもGoogleで検索した方が的確なことが多い。)被引用を付けてくれるシステムに更新するにはそれなりに費用がかかるだろうし,投資に見合う収入増を見込めないので導入されないのだろう。(読者を自社サイトに滞留させることができず,他サイトに逃す機会損失があるとしても。一旦Googleに出れば戻ってくるとは限らない。)

これはもう何年も前にインプレスに要望したことだが,依然として変わらない。ただ,2010年に最新の設備投資をして始まったはずの日経電子版(詳細は別記事NET/日経新聞電子版参照)でも,被引用のリンクは提供されていない。「類似している記事(自動検索)」等で擬似的に実現しているにとどまる。このままでは,「勝手に被引用」なる外部サービスが登場しかねないな。

NHKのウェブページで文字化け Edit

問題の所在 Edit

NHKのウェブページをWeb::Scraperで取得して加工することがよくある。一つ難があり,文字化けすることがある。原因は,NHKはページの文字コードを「Shift_JIS」と名乗っているのに,実際には,Shift_JISから外れた「Windows機種依存文字」を偶に(必要に応じて?)使っているため。例えば「山﨑努」。固有名詞という理由(大義名分)だろうか。

  • 気付いたのは,明日(執筆は2010年7月25日)の衛星映画劇場「地の涯に生きるもの」。昨日の朝日新聞土曜版「サザエさんをさがして 知床旅情」にこの映画のことが出ている。

こうした文字はShift_JISではなく「cp932」等と呼ばれる文字コードなら(一応)許される。しかし,ページが名乗っている文字コード名をそのまま受け入れるソフトウェア(Web::Scraperもその一つ)は,Shift_JISにない機種依存文字であり,未定義文字だと理解して,1バイト目を「置換文字」(U+FFFD)に変換してしまう。(2バイト目は半角カナなどに変換される。)そのため,人間にとっては文字化けする。

  • U+FFFDが画面上どのように見えるかは状況次第。?と表示されることもあれば,\x{fffd}と表示されることもある。

対処 Edit

Web::Scraperを呼び出す前に,

use Encode::Alias;
define_alias( qr/shift.*jis$/i  => '"cp932"' );

を加える。

補足 Edit

\x{fffd}という文字列に変換されるのは,画面等への出力時(encode時)。Web::Scraperは「﨑」をU+FFFDとU+FF71の2文字へ成功裏に変換する。その後,Encode:encodeやbinmodeなどがShift_JISまたはcp932に変換する際に\x{fffd}に変換する。

  • Web::ScraperやLWP::Simpleなどのお任せツールは,自動的に内部表現(Unicode)にdecodeしてくれる。

Web::Scraperの挙動は正しい仕様であり,おかしなことをしているのはあくまでもNHKである。しかし現実問題として情報が失われている。世の多くのブラウザーは「Shift_JIS」と「cp932」を厳密に区別しない*1。善し悪しはいわゆる波ダッシュ問題としても議論されている。さて,波ダッシュ問題は意味的に別の文字になってしまう,だが一定の法則があるので元の文字を推測できる*2。これに対し,今回の問題は元の文字が何だか分からなくなってしまう。より深刻と言えば深刻。

波ダッシュ Edit

ただ,なんでもcp932にすればよいわけではない。というのも,「cp932はshift_jisに機種依存文字を加えたもの」ではないからだ。(そうだったら話は簡単だったのに。)この典型が波ダッシュ問題。波ダッシュ(~)の書かれたページの設定が,Shift_JISのときとcp932のときとでは,その後の運命が違う。議論があるが,簡単に言えば,cp932のときは(Web::Scraperなどで取得されると)別の文字(見た目はよく似ているが)になってしまう。そして,NHKのページには波ダッシュが多用されている。

もっとも先述のように,この問題はたいていの場合元に戻すことができるし,全文検索などでも対処可能なので,それほど大きな問題ではない。

外字まで Edit

NHKのウェブページには「外字」(Windowsの利用者定義文字)が使われていることもある。例えば,「長崎県女クラスメイト」という記述を今日(2010年 8月 7日)見つけた。「女ク」の間の文字がどのように表示されるかは読み手が使っているソフトウェア(ブラウザー等)次第であり,例えばIE 8 on Windows 7やGoogle Chrome 6.0では「□」のように表示され,FF 3.6ではもっと直截に「普通じゃない文字」であることが分かるように表示される。NHK社内で使っている特別な文字・記号(業界の記号か何か?)がそのまま公開ページに出てきてしまったと推測される。NHK社内ではどのような文字を当てているのだろうか?(実際の放送を見ると,単なる空白になっていた。意味的にも空白となるべき場所。空白であることが見た目明確に分かるようにするための記号が当てられているのかも。)

テーブルをTSVに変換 (TABLE to TSV) Edit

ブラウザーに表示されている表・テーブル(HTMLの)をTSVに変換したいことはよくある*3。FFではテーブルを普通にコピーすれば標準でそうなるが*4,IE 8は今のところ違う。(IEからエクセルにコピーすれば最終的にTSVにできるので,昔はこのためだけにエクセルを起動した。)

IEの右クリックメニューに「テーブルをTSVでコピー」のような項目を追加することができる。登録の仕方は,マイクロソフトサポートオンラインの「ブラウザの標準コンテキスト メニューに項目を追加する」を参照。

<SCRIPT LANGUAGE="JavaScript" defer>

	var pukiwiki = 1; // colspanを['','a']とするか,['a','']とするか。
	var plaintext = 1; // セル内のタグ(BRやSMALLなど)を除去するか。

	var el = external.menuArguments.event.srcElement; 
	while ((el != null) && (el.tagName != "TABLE")) {
		el = el.parentElement;
	}

	// 行(TR)に分ける。
	var tr = el.innerHTML.split("<TR");
	// 列(TD)に分ける。
	var table = [];
	for (var i=0; i<tr.length; i++) {
		tr[i] = tr[i].replace(/[\r\n]+/g, "");
		tr[i] = tr[i].replace(/<TH/ig, "<TD");
		tr[i] = tr[i].replace(/<\/TH/ig, "</TD");
		var td = tr[i].match(/<TD.+?(?=<\/*T[DR])/ig); // 配列に。
		if (td != null) {
		// 空行の削除。
			table.push(td);
		}
	}
	// colspan
	for (var i=0; i<table.length; i++) {
		for (var j=0; j<table[i].length; j++) {
			// タグの中,>の前に別のタグが入っていることがある。
			// それは""で囲まれているはず。有無を言わせず削除。
			table[i][j] = table[i][j].replace(/(<TD[^>]+?)\w+=\"[^"]+\"/ig, "$1");
			if (table[i][j].match(/<TD[^>]*colspan="*(\d+)"*[^>]*>/i)) {
				// spliceで配列を伸ばせない。多次元配列が入る。Perlと違う。
				// spliceは使えない。
				// sliceは始点と終点が同じだと空を返すのでこれも使えず。
				var mae = [];
				for (var k=0; k<j; k++) {
					mae.push(table[i].shift());
				}
				var here = [];
				here.push(table[i].shift()); //table[i][j]を取出す。
				for (var k=1; k < RegExp.$1; k++) {
					if (pukiwiki == 2) {
						mae.push(">"); // tabを前に付ける。完全PukiWiki。
					} else if (pukiwiki) {
						mae.push(""); // tabを前に付ける。PukiWiki式。
					} else {
						here.push(""); // tabを後に付ける。
					}
				}
				// <TD >の中身を捨てない。colspan="\d+"のみ捨てる。
				here[0] = here[0].replace(/colspan="*\d+"*/i, "");
				var ato = table[i];
				table[i] = mae.concat(here,ato);
			}
		}
	}
	// rowspan
	for (var i=0; i<table.length; i++) {
		for (var j=0; j<table[i].length; j++) {
			if (table[i][j].match(/<TD[^>]*rowspan="*(\d+)"*[^>]*>/i)) {
			// <TD ...>の中に別のタグが入っていることがある。
				var offset = RegExp.$1;
				offset-=0;
				offset+=i;
				for (var k = i+1; k < offset && k < table.length; k++) {
					// 一つ下の行からi+RegExp.$1行まで,列を増やす。
					var mae = [];
					for (var l=0; l<j; l++) {
						mae.push(table[k].shift());
					}
					if (pukiwiki == 2) {
						mae.push("~");
					} else {
						mae.push("");
					}
					var ato = table[k];
					table[k] = mae.concat(ato);
				}
			}
		}
	}
	var html = '';
	for (var i=0; i<table.length; i++) {
		for (var j=0; j<table[i].length; j++) {
			table[i][j] = table[i][j].replace(/<TD[^>]*>/i, "");
			if (plaintext) {
				table[i][j] = table[i][j].replace(/<\/*[^>]*>/ig, "");
			}
			table[i][j] = table[i][j].replace(/&amp;/g,"&");
			table[i][j] = table[i][j].replace(/&lt;/g,"<");
			if (pukiwiki < 2) {
				table[i][j] = table[i][j].replace(/&gt;/g,">");
			}
			table[i][j] = table[i][j].replace(/&quot;/g,'"');
			table[i][j] = table[i][j].replace(/&#39;/g,"'");
	 	}
	 	html += table[i].join("\t");
	 	html += "\n";
	}
	clipboardData.setData("text",html);

</SCRIPT>

FF同等 Edit

FireFox 3.6やTableTools For FireFox (T2F3) (v0.28)の作るTSVと同等。セルの連結は無視される。

<SCRIPT LANGUAGE="JavaScript" defer>
	var el = external.menuArguments.event.srcElement; 
	while ((el != null) && (el.tagName != "TABLE")) {
		el = el.parentElement;
	}
	var html = el.innerHTML;
	
	html = html.replace(/[\r\n]+/g, "");
	html = html.replace(/<TH[^>]*>/ig, "\t");
	html = html.replace(/<TD[^>]*>/ig, "\t");
	html = html.replace(/<TR[^>]*>/ig, "\n");

	html = html.replace(/<\/TH[^>]*>/ig, "");
	html = html.replace(/<\/TD[^>]*>/ig, "");
	html = html.replace(/<\/TR[^>]*>/ig, "");

	html = html.replace(/<\/*TBODY[^>]*>/ig, "");
	html = html.replace(/<\/*THEAD[^>]*>/ig, "");
	html = html.replace(/<\/*COL[^>]*>/ig, "");
	html = html.replace(/<\/*TABLE[^>]*>/ig, "");

	html = html.replace(/^[\r\n]+/mg, "");
	html = html.replace(/^\t/mg, "");
	html += "\n";

	clipboardData.setData("text",html);
</SCRIPT>

*1 正確には,波ダッシュ問題に見るように,首尾一貫しない解釈をする。
*2 この限りでは首尾一貫している。
*3 TSVにすれば,PukiWiki Tableを介してPukiWikiのテーブルにも簡単に変換できる。
*4 直接エクセルにコピーすると駄目。しかも,そもそもTSVにできると言っても中途半端。列や行の連結(セルの連結)は無視される。

添付ファイル: filehatena_help_cookie.png 138件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2014-03-08 (土) 18:14:46 (1351d)