C# 習作1:クッキー取得クラスCookieGetter

要件

このクラスは、Webブラウザからある特定のURLのクッキーを取得するためのC#で作成したクラスです。
具体的な目的は、ニコニコ動画のセッションIDをCookieから取得するためです。

対応しているWebブラウザは、Internet Explorer 7、Firefox 3、Opera 9、Safari 3です。(今のsafariには使用できません・・・。XMLからバイナリ形式になって構造が分かりません)
その他のWebブラウザ、バージョンには対応していません。
Firefox 2は、Firefox 3とCookieの保存ファイルが違うため、使えません。(ウチにFirefox 2がないのでプログラムを確認しながら作れません)
IEや最近のOperaは、ある程度バージョンが違っても使えるかもしれません。試していないので、以下に書いてある技術的覚書を見て、確認してみてください。

使用方法

ここからCookieGetterプロジェクトZIPファイルをダウンロードして、ビルドしてください。
 ※:上記のプロジェクトはバグがあり、しかも修正しておりませんので、以下のプロジェクトを使用していただきたい。
   ニコ動のCookieを各Web取得してWebBrowserオブジェクトに投入するテストプログラム。
このZIPファイルのCookieGetterは、Microsoft Visual C# 2008 Express Editionで作成したプロジェクトを固めたものです。
#初版はMicrosoft Visual C# 2005 Express Editionで作ってます。

.NET Framework上で動作します。古いOSでは動かないでしょう。今時のPCならVISTAか、XPなので問題なし!2000?知らんな。ox 3のCookieを本プログラムは、Firefox 3のCookieを取得するのにSQLite 3のライブラリを使用しています。sqlite3.dllおよびSystem.Data.SQLite.dllを正しく入れてください。(パスの通っているところに置く。System.Data.SQLite.dllは参照設定をする)

SQLite.dllは、本家HPから(上の方にある)メニューDOWNLOAD→Precompiled Binaries For Windowsにあるどれかで sqlite3.dll を取得する。例えば2009/11/22現在最新であるsqlite3_analyzer-3.6.1.zipとか。sqlite3.dllは、パスが通っているところに入れる。別にCookieGetterを動かすAPと同じディレクトリにあってもよい。 C#ラッパDLLは、sourceFORGEから拾ってくる。System.Data.SQLite.DLLが必要。SQLite-1.0.65.0-source.zip を落として、binディレクトリにある System.Data.SQLite.DLL をアプリのexeがあるところに置けば良い。

注意:初版では、エラーケースを考慮していませんので、Cookieファイルがない、DLLがないその他の原因で例外が発生するかもしれません。適宜直しておいてください。気が向いたら直します。

バグ情報

CookieGetterバグ管理表

バージョン情報

2012/04/08(Webテスト)

Cookie取得をSQLiteを使用するWebブラウザ(FireFox、Chrome)で2回以上連続してCookie取得するとException発生するバグを修正しました。
不要なオブジェクトを解放するIFの追加と、オブジェクト登録のIFを整理しました。
WB_CookieプロジェクトZIPファイルはこちら。

2009/11/23リリース版(第2版)

いろいろバグフィックスしました。
・firefoxでSQLiteのDLLを静的リンクから動的リンクに変えました。これにより、ビルドしたときのSQLiteのDLLのバージョンのくびきから解放されました。
・IEやfirefoxのクッキーから値を取得した後、カレントディレクトリが変わってしまい、ディレクトリを指定しないファイルの参照・出力を行ったときファイルが見つからないエラーや予期しない場所へのファイル出力される問題を修正しました。
・Microsoft Visual C# 2008 Express Editionで作成しました。

CookieGetterプロジェクトZIPファイルはこちら。プロジェクトファイルのみで実行ファイルは添付しておりませんので、ビルドしてください。

2008/9/6リリース版(初版)

とりあえず作ってみたよ。
Internet Explorer 7、Firefox 3、Opera 9、Safari 3をサポート。
Microsoft Visual C# 2005 Express Editionで作成しました。

CookieGetterプロジェクトZIPファイルはこちら。プロジェクトファイルのみで実行ファイルは添付しておりませんので、ビルドしてください。

技術的覚書

Internet Explorer 7について

注:IE 7.9.6001.18000で確認した内容です。

IE 7のCookieは、<APPDATA>\Microsoft\Windows\Cookies\Low\ディレクトリの下に格納されています。
<APPDATA>\Microsoft\Windows\Cookies\ディレクトリの下にもあるけど、なんか違うみたい?
<APPDATA>は、環境変数APPDATAの値。例えばカレントディスクがCドライブでユーザ名がpokopenなら、C:\Users\pokopen\AppData\Roaming となります。

Cookieのファイルは、どうやらURLごとに作られる模様。
ファイル名は、<ユーザ名>@<url>[<?>].txt らしい。
※:<ユーザ名>は接続ユーザ。環境変数USERNAMEの値。
※:<url>はCookieを設定したWebサイトのURLの変形名(?)。ドメインといった方が正しいのか?
よくわからんのだが、例えばニコニコ動画(www.nicovideo.jp)は、"nicovideo"になる。前と後ろを消したものかと思いきや違うものもあるので、法則がわからん。
※:<?>は、ユニークな番号。1が入ることが多いが、2が入っているものもある。法則がわからん。

ファイルの内容は、以下のようにテキストで格納されている。
(1)Cookie キー名
(2)Cookie 値
(3)ホストURL
(4)?
(5)?有効期限か?
(6)?
(7)?最後に使われた日時か?
(8)?
(9)* :区切り。次行が次のCookieキー名

まあ、全くわからん。とりあえず、URL、キー名と値がわかればよしとしよう。

Firefox 3について

注:Firefox 3.0.1で確認した内容です。

Firefox 3からCookieは、SQLite3を使うようになりました。(中身を解析して自前で読み取るより、さっさとSQLite3のライブラリを使った方が楽)
Firefox3のCookieは、<APPDATA>\Mozilla\Firefox\Profiles\<ランダムの文字列?>\cookies.sqlite ファイル。
※:本当に<ランダムの文字列?>はランダムの文字列なのか不明。ググったらそう書いてあった。
仕方がないので、Profilesフォルダからcookies.sqliteファイルを検索する。(Profilesフォルダには、1つしかサブディレクトリがないのだけれど、保障されているわけでもないので、仕方がない)

C#からSQLiteを使うには、以下のファイルを使う。http://www.sqlite.orghttp://sourceforge.net/project/showfiles.php?group_id=132486&package_id=145568から取得した。
sqlite3.dll ←SQLite本体。パスのある所に置く。 (sqlitedll-3_6_1.zipを展開した中にあり)
System.Data.SQLite.dll ←C#でのラッパ。Visual Studio 2005 C#から参照の指定をした。(SQLite-1.0.56.0-managedonly-binaries.zipを展開した中にあり)
System.Data.SQLite.XML (同上)

テーブル名は、moz_cookies。
カラムは、host, path, isSecure, expiry, name, value, isHttpOnly 。
※:出典 もじら組「cookies.sqliteからcookies.txtに変換」

特定のURLとキー名から値を取り出すには、以下のSQL文を実行する。
SELECT value FROM moz_cookies where host=='<url>' AND name=='<key>'
※:<url>は検索するURL、<key>は検索するキー名。

Opera 3について

注:Opera 9.5.2で確認した内容です。

Opera 9のCookieは、<APPDATA>\Opera\Opera\profile\cookies4.dat ファイル。
バイナリ形式で格納されていますが、内容は分かりやすいです。
※: Ashula.infoさん 「cookies4.dat」がわかりやすく解説されています。ありがたや。

ファイルの内容は、ヘッダ部分とデータ部分から構成されている。
ヘッダ部分は、データのバージョン、Applicationのバージョン、そしてタグIDおよびデータ長の格納サイズが記されている。
データ部分は、以下のように構成されていて、これが繰り返す。またパート(大分類)のデータ部分は、細かいデータ(小分類)に分かれる
(1)タグID
(2)データ部分のデータ長
(3)データ

タグIDの最上位ビットがONの場合、タグIDのみのデータで、(2)(3)はない。最上位ビットは、ヘッダ部分のタグIDの格納サイズにより値が変わるので注意。(Windows版だとタグIDの格納サイズは0x01なので、MSB0x80と論理積をとって0でなければタグIDのみのデータとなる)
データは、まずDOMAINレコードが来て、データ部分に(1)~(3)の構造でDOMAIN名が入る。
次にPAGEレコードが来て、そのデータ部分に(1)~(3)の構造でPAGE名がくる。ない場合もある。
次にCOOKIEレコードが来て、そのデータ部分に(1)~(3)の構造でCOOKIEのキー名、COOKIEの値、有効時間などが入り、おなじDOMAINのCOOKIEが連続して入っている。
そして、COOKIEレコードの終わりを示すタグID,PAGEレコードの終わりを示すタグID,DOMAINレコードを示すタグIDが続く。
ここら辺は面倒なので、本プログラムでは次のDOMAINレコードのタグIDが出てきたら、前のDOMAINのおしまいにした。(ちゃんとやれよ)

タグIDの種類や詳細な仕様については、上記のAshula.infoさん 「cookies4.dat」Opera File Formats(私家訳)を参照してください。

Safari 3について

注:Safari 3.1.2で確認した内容です。

Safari 3のCookieは、<APPDATA>\Apple Computer\Safari\Cookies\Cookies.plist ファイル。
XML形式で格納されていて、内容は分かりやすい。
というか見たまんま。
<key>タグの内容で次のタグのデータが何かを示している。
<key>タグの内容(推測)
・Created:作成日付?
・Domain:Domain名(urlと思っていい?)
・Expires:有効期限
・Name:Cookieのキー名
・Path:パス
・Value:Cookieの値
<Key>タグの次のタグは、データ型を示している。
・<real>タグ:実数 作成日付で使用。
・<string>タグ:文字列 Domain名、Cookieのキー名、パス、Cookieの値で使用。
・<date>タグ:日付 有効期限で使用。

その他

・バイナリのファイルを一気に読みこむとき、以下のようにした。
    FileStream reader = new FileStream(filename, FileMode.Open, FileAccess.Read);

    // バイナリ読み込み
    BinaryReader binReader = new BinaryReader(reader);
    // 指定したアドレスに読み込み位置を移動
    reader.Seek(0, SeekOrigin.Begin);
    // 読み込み
    data_ = binReader.ReadBytes((int)reader.Length);

    binReader.Close();
    reader.Close();

・byte配列のデータを一部分コピーするのは、以下のようにArray.Copyを使う。
    Array.Copy(data, index, recordData.bytepayload, 0, copyLength);

・べき乗は、Math.Pow()を使う。引数や戻り値はdouble型になるけど・・・。”^”は、ビットごとの排他的論理和になるので注意。

・動的にDLLを読み込むプロセスは、(1)DLLの読み込み(モジュールの読み込みとクラスの読み込み) (2)クラスTypeの取得→クラスのインスタンス生成 (3)Method/PropertyTypeの取得→メソッド・プロパティのオブジェクト生成→メソッド・プロパティの実行 となっております。
 CookieGetterでは、classLoadModule.csにまとめて、classFirefoxCookieGetter.csで使用しております。難解な感じに仕上がっております。反省。(きっと1週間後には使い方忘れてるな)

免責・お願い

本プログラムは、商用利用および個人利用、そして改造を自由に行ってくださってもかまいません。
ただし、C#の更なる発展のため、改造したソースは公開してください。
利用・改造の連絡は不要です。
なお、本プログラムの利用によりあなた、またはあなたの周囲に損害が発生しても、 当方は一切関知しません。

USE AT YOUR OWN RISK!


履歴

初版 :2008/09/05:C#の勉強がてら、とりあえず動くかも知れないものを作った。少なくともうちのマシンでニコニコ動画のセッションIDはとれた。

第2版 :2009/11/23:バグフィックスとfirefoxでのクッキー取得のときに使うSQLite DLLを動的に読み込むように変更。