aswww log

エンジニアの技術録。アプリとかウェブとか

負のスパイラル突入中

更新頻度が低くて管理人不在に思われちゃうとアレなので現状報告を。

ここ一ヶ月作り→手戻り→作り→追加要件による手戻り→作りみたな感じで、かなり生産性無い具合に忙しい感じです。
こういう時だからこそ書きたいネタが沢山なのですが、更新する時間も惜しんじゃう現状。
技術ネタはそこまで鮮度重視じゃないのでとりあえず下書き保存して後々公開することにしましょう。

直近の課題としてモチベーション管理です。会社勤めの時は残業のだらけでも残業代が出るっていうかなり大きいモチベーションアップ要素があったのですが、フリーの場合だと時間かけるだけ自分が損なのでそれは使えませんね。

うーん、、、難しいですね。。。

oilによるViewとController生成

FuelPHPのoilコマンドでController・Viewの枠組みがだけ生成する方法。

php oil g controller Controller名 [メソッド名1] [メソッド名2]...

これをするとControllerとそのメソッドに紐づくviewファイルを生成してくれる。
例えばこんな感じ。

php oil g controller login index
	Creating view: /[APPPATH]/views/login/index.php
	Creating controller: /[APPPATH]/classes/controller/login.php

地味にめんどくさいクラス追加作業が一行で終わっちゃう。
不精さんにオススメ。

ちなみに他にViewModelとかも一緒に生成してくれるコマンドもあるけど、今回はModel・View・Controllerしか使わない予定なのでこれで十分なり。

phpでhtmlをparseする方法まとめ

スクレイピングバッチにかかせないのがhtmlのparse。いくつか方法をためしたのでまとめて見る。

1)PDOMDocumentとかを駆使して連想配列化する方法
 取得するHTMLによれば、おそらく最も手間がかからない方法。 手順は以下のとおり。

・file_get_contents()でHTML取得
・DOMDocumentのloadHTML()を使用してHTMLをXMLへ整形
・simplexml_load_string()でSimpleXMLElementオブジェクトへ変換
・json_encode()でJSON化。更にjson_decode()してArray化。

ただ、loadHTML()時に一番上にXMLタグが無いだけで怒られるし、file_get_contents()の時点で文字コード変換したのに何か文字化け(?)で怒られたりして使用を断念。

参考:PHPでHTMLをパースして解析する簡単な方法

※ちなみにDOMDoccumentが使えるかどうか調べるためのソースは以下のとおり。

<?php
print_r(get_loaded_extensions());
print_r (get_extension_funcs ("DOM"));

参考
PHPでDOM のモジュールが使えません!

2)Simple HTML DOM Parserを使用する方法
 結構有名なライブラリ。HTML取得からオブジェクト化までをfile_get_html()でやってくれるスグレモノ。導入方法と使い方を以下のとおり。

・zipファイルをダウンロードし、"simple_html_dom.php"のみを任意のディレクトリにコピーする。
phpファイルにてrequire(任意のディレクトリ/simple_html_dom.php)する。
・file_get_html()を使用してHTMLがParseされたオブジェクトを取得する。
 ※simple_html_dom.phpは関数集なので直接関数を呼んでしまって良い。

あとは取得したオブジェクトに$html->find('a')とか$html->find('img', 0)->srcとかして情報を取得する。(jQueryチックな操作感)やや柔軟だが、やはりタグが閉じられてなかったりするとお手上げ。あと重い。でも人気。解説サイトもたくさんある。

参考
PHP Simple HTML DOM Parser Manual(本家?)
PHP Simple HTML DOM Parser
誰でもスクレイピング!DOM要素を引っこ抜くSimple HTML Dom

3)preg系関数で正規表現とかを用いて頑張ってParseする方法
 これが一番めんどくさくいけど一番柔軟で一番確実な方法。1)2)で紹介した方法を用いた場合でも最終的にはこれを併用することになるのではないかな。よっぽど整形されたHTML相手でなければ。やり方はHTMLソースとにらめっこしてほしい情報をpreg_split()やらpreg_replace()を用いて一個一個取得する感じです。

参考
PHP マニュアル


他にも触ってないけどphpQueryというライブラリが気になった。名前のとおりjQueryライクな感じで要素へアクセスできるらしい。時間あるときに試したい。

参考
スクレイピング応用編-phpQuery
スクレイピング用おすすめライブラリ『phpQuery』の基本的な使い方

PHP正規表現でエスケープがうまくいかなったらバックスラッシュを使おう

とあるサイトのスクレイピングバッチを作成している最中、正規表現で思わぬとこでハマったのでメモ。

○事象
文字列"$(initLive);"を空文字に置換(つまり削除)したかった。以下のとおり実装。

preg_replace("#[\$]\(initLive\);#", '', $contents)))));

デリミタは一般に"/"(スラッシュ)がよく使われるけど、今回はテキストHTML相手なのでエスケープもめんどくさいし、"#"(ナンバー記号)を使用。"$"(ダラー)と"("(前括弧)と")"(後括弧)は文字列として判定してほしいので"\"(円マーク)でエスケープする。
しかしこれで実行してもエラーが出てしまった。

どう考えても構文は間違っていない...そこでひとつ気になったことが。以前の仕事でCentOS上で正規表現使った時、"\"(バックスラッシュ)でエスケープしたような。
試しに"\"(円マーク)を"\"(バックスラッシュ)で打ちなおしてみる。

preg_replace("#[\$]\(initLive\);#", '', $contents)))));

見かけ全然変わらないけど、再度実行したらいけました。
外見は同じでも内部では文字コードで判別してるのね。そうだよね、見かけに騙されちゃダメだよね。
でも以前Windowsで実装してた時は\(円マーク)でいけた気がするんだけどな?UbuntuLinux仕様なのか?

レンタルサーバでfuelPHPでoil実行するときの注意点

注意点というか実はとても簡単で当然のことかもしれないけど、私自身簡単なこととか当然のことができなくてドハマリするタイプなので書いときます。ちなみにこの問題で私は3日間費やしました。はぁ。

ちなみにレンタルサーバのスペックは

・PHP5.1〜PHP5.5まで対応
・コマンドラインからのphp実行OK(引数も渡せる)

PHPのバージョンは管理画面で変更する仕様になっているものの、いざコマンドでphp -vしても常にPHP5.1が表示されてしまうため、whereis phpで取得した絶対パスを指定して使用することにしました。

oilと同じディレクトリに移動して以下を実行。

/usr/bin/php5.4 oil r robots

すると以下のエラーが出力された。

The use of oil is not supported when running php-cgi. Oil needs php-cli to function!

このエラーメッセージをそのままググってもわからず。2日間試行錯誤した後、3日目に知り合いのスーパーSEにヘルプを投げかけたところ
phpがcgi版でコンパイルされているから使えない。cli版のphpを使えカス。」
といった具合のありがたいアドバイスをいただいた。
そこで再度whereis phpをしてみると。。。あった!もうひとつ/opt/php5.4/bin/phpってやつがあった!こっちがcli版ってやつか!これで実行してみよう!

/opt/php5.4/bin/php oil r robots

					"KILL ALL HUMANS!"
			          _____     /
			         /_____\
			    ____[\*---*/]____
			   /\ #\ \_____/ /# /\
			  /  \# \_.---._/ #/  \
			 /   /|\  |   |  /|\   \
			/___/ | | |   | | | \___\
			|  |  | | |---| | |  |  |
			|__|  \_| |_#_| |_/  |__|
			//\\  <\ _//^\\_ />  //\\
			\||/  |\//// \\\\/|  \||/
			      |   |   |   |
			      |---|   |---|
			      |---|   |---|
			      |   |   |   |
			      |___|   |___|
			      /   \   /   \
			     |_____| |_____|
			     |HHHHH| |HHHHH|

できた!ありがとうスーパーSE!

レンタルサーバ使うときは想定外のモジュールがインストールされていることがあるってわかったし、気を付けよ!

Ubuntu12.04にeclipseを手動でインストールすることにした

Ubuntuソフトウェアセンターでインストールしたeclipseを使っていたら、プラグインが追加できなくなった。調べてみたらeclipse/pluginディレクトリの書き込み権限がrootのみになっていた。
これが直接原因かは不明だが、今後権限でめんどうなことになるのはイヤなので改めて手動インストールすることにした。

参考にしたサイトは以下のとおり。
Ubuntu12.04にEclipse (Juno)を手動でインストール

上のサイトで詳しく解説されいるため、ここではほぼコマンドのみ記載する。

#eclipse解凍
sudo tar -xvzf eclipse-standard-kepler-R-linux-gtk-x86_64.tar.gz 

#コマンドで起動できるようにシンボリックリンク作成
sudo ln -s /opt/eclipse/eclipse /usr/local/bin/eclipse

#ランチャー登録用のeclipse.desktop作成
sudo touch /usr/share/applications/eclipse.desktop

#eclipse.desktop編集
#内容は以下のとおり
#############################
#[Desktop Entry]
#Type=Application
#Name=Eclipse
#Comment=Eclipse Integrated Development Environment
#Icon=/usr/local/eclipse/icon.xpm
#Exec=eclipse
#Terminal=False
#Categories=Development;IDE;Java;
#############################
sudo vi /usr/share/applications/eclipse.desktop

#pleiades解凍(プラグイン個別配布してるやつ)
sudo unzip pleiades.zip

#日本語化に必要なモジュールをコピー
sudo cp -r /usr/local/src/pleiades/features/jp.sourceforge.mergedoc.pleiades/ /usr/local/eclipse/features/
sudo cp -r /usr/local/src/pleiades/plugins/jp.sourceforge.mergedoc.pleiades/ /usr/local/eclipse/plugins/

#eclipse.iniを編集
#以下を追記
#############################
#-javaagent:/usr/local/eclipse/plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar
#############################
sudo vi /usr/local/eclipse/eclipse.ini

#eclipseをcleanで起動
eclipse -clean &

pleiadesはプラグインのみダウンロードできるやつが画面下部にあるのでそれをダウンロードすること。(PlatformはLinux非対応)

Ubuntuから公開鍵認証でssh接続を試みる[解決]

Ubuntuからターミナルで公開鍵認証方式でしか接続できないレンタルサーバssh接続を試みた。結果うまくいかなかったが、備忘録的に途中経過をまとめとく。
★2013/08/09追記 解決しました。


◆まずはレンタルサーバにて公開鍵認証用鍵ペアの生成
 使用するレンタルサーバのマニュアルを見てみる。SSH設定の項目に以下のとおり書いてあった。

本サーバのSSH接続では「公開鍵認証」にのみ対応しています。
(※パスワード認証には対応していません。)
そのため、SSHで接続する為にはサーバー上に公開鍵の登録を行う必要があります。
やり方としてはサーバーで公開鍵認証用鍵ペアを生成し秘密鍵をダウンロードしてする方法と、お客様の環境にて生成の公開鍵を登録していただく方法がありますので、以下をご参考の上、生成、または登録を行ってください。
(※登録が行える公開鍵は、「OpenSSH形式」のみです。)

というわけで手軽でつまづかなそうな「サーバーで公開鍵認証用鍵ペアを生成し秘密鍵をダウンロード」で接続することに。
サーバパネルの[SSH設定]項目に[公開鍵認証用鍵ペアの生成]がフォームがあるのでそこにパスフレーズを入力して登録。するとサーバ上の公開鍵が更新され、それに対する秘密鍵がダウンロードできるようになった。

ダウンロードした秘密鍵をローカルUbuntuの~/.ssh/配下に配置。以下を実行して接続を試みる。

ssh ユーザ名@サーバアドレス -p ポート番号 -i ~/.ssh/秘密鍵ファイル名

すると以下のエラーが出力された。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0664 for '/home/ユーザ名/.ssh/秘密鍵ファイル名' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /home/ユーザ名/.ssh/秘密鍵ファイル名
Permission denied (publickey,gssapi-with-mic).


Permissionがうんぬん。調べて見ると秘密鍵ファイルのPermissionが0600じゃないといけないことが判明。変更し、再度ssh接続を試行。

sudo chmod 0600 ./.ssh/秘密鍵ファイル名

ssh ユーザ名@サーバアドレス -p ポート番号 -i ~/.ssh/秘密鍵ファイル名

するとパスワードが聞かれるものの、またエラーが出力された。

passphrase for key '/home/ユーザ名/.ssh/eir001.key': 
Permission denied (publickey,gssapi-with-mic).

また調べて今度はsshコマンドに-vオプションをつけて実行。デバッグ情報が見れるもERRORの文字もなく、一旦ここでタイムアップ!ちなみに-vvvとかすると更に詳細なデバッグ情報が見れるらしい。明日以降トライしよう。



★2013/08/09追記
今日になって改めて接続を試みたらなんとユーザー名が間違っているだけで普通にssh接続できました!orz
ちなみに調べているうちにはてなの質問ページでssh接続が出来なかった時のための対処法が箇条書きでわかりやすくまとめられていて今後役に立ちそうなのでそれをここで引用してのせさせていただきます。

人力はてな ーSSHの設定方法の質問ですーの回答より
http://q.hatena.ne.jp/1149079199

・クライアント側の/etc/ssh/ssh_config、~/.ssh/configでサーバBに対する設定、
 ~/.ssh/id_rsaの鍵が使われているかどうか
・サーバ側の/etc/ssh/sshd_configで公開鍵認証が有効になっているかどうか、
 ~/.ssh/authorized_keysでクライアント側の~/.ssh/id_rsaに対応する公開鍵が入っているかどうか
・サーバ側の~/.ssh/authorized_keysのパーミッションが600になっているかどうか
・サーバ側の~/.sshのパーミッションが700になっているかどうか
・ssh -vでつないでうまくいっているサーバへの接続と失敗するサーバへの接続を比較する。
・ssh -vでわからなければssh -vvやssh -vvvなどと-vを増やして試してみる。


参考:
・MacでSSH公開鍵・秘密鍵ファイルをコピーして使ったら警告がでた
http://blog.ruedap.com/2011/04/04/mac-ssh-key-copy-error
sshでPermission denied (publickey,gssapi-with-mic).のエラーが出た時の対処方法
http://d.hatena.ne.jp/puchiban/20111228/1325069112