2003/09/03Samba242ちゃんねるとお話するための方法をまとめたメモです。rawモード2ちゃんねるの仕様は日々変わっていくので、ここに書いてある情報は古いかもしれません。間違え・仕様変更などがあれば掲示板の方へ書き込んで教えてくれると非常に助かります。最新情報Samba24という規制が始まった模様。1000000000と定義します。基本はこの3つだけです。簡単ですね?では、どんどんいってみよー。HTTP_OKが返ってくる。この例の場合、要求ヘッダでgzip圧縮を受け入れるようにしているため、応答ヘッダで圧縮されているか確認して、必要ならば解凍しなければいけない。圧縮されたかどうか確認するには、応答ヘッダContent-Encodingにgzipがあるか調べる。2chでは、転送量問題が発生した時から、データをgzip圧縮して返すことを推奨(必須?)している。圧縮要求しなければデータを取得できない、なんてサーバもあったような気が。ユーザエージェントは、とりあえずモナジラと名乗っておきます。subject.txtが更新されていなかったらデータを取得しないように、If-Modified-Sinceを付けて要求するのも、無駄な負荷を減らすポイントです。bytes=ローカルDATのファイルサイズ-ファイルサイズの単位はバイト。ローカルdatは2chのdatと完全に同じであることが前提条件。Windowsデフォルトの改行は\r\n、2chデフォルトの改行は\nなので、1バイト×レス数のファイルサイズ不一致、という罠に嵌りやすいので注意。ローカルdatが2chと違う仕様なら、受信したデータのサイズ(解凍後)を累積記録などして、それを使用する。If-Modified-SinceとDateヘッダの値は、RFC1123形式で表される時刻。HTTP_PARTIAL_CONTENTが返ってきて、差分データを取得できる。HTTP_NOT_MODIFIEDが返ってくるあぼーんがあった場合、ファイルサイズ不一致により、データが取得できません。HTTP_RANGE_NOT_SATISFIABLEになります。参考までに、あぼーんをより確実に検出するために、次のような工夫をして差分取得しているブラウザもあるようです。If-Modified-SinceにリモートDATの更新時刻、rangeに取得済みDATのサイズマイナス1を指定して要求する。HTTP_NOT_MODIFIEDが返ってきて、データは送信されない新着あり、つまりContent-lengthが2以上の場合は、受信データの先頭を確認して\nだったら正常、\n以外だったらあぼーん。新着なし+あぼーんがあった時は416。(ローカルDAT>リモートDAT)DAT落ちを取得2chでは次のようにスレッドが変遷しますスレッドが立てられるライブスレッド一定期間書き込みがない場合や1000を超えた場合、DAT落ちする過去ログ化DAT落ちのスレは、IDを購入してログインしないと閲覧できない仕組みになっています。ログイン方法はログインの項目をお読みください。ログインしてSESSION-ID(sid)を受け取れば、後は通常のDATと同じように取得します。詳しく知るには、これもログインの項目を見てください。/板キー/kako/スレキーの上位3桁/スレキー.dat.gzdat.gzは既にgzip圧縮されています。解凍すれば通常のDATファイルになります。ブラウザで見るには拡張子dat.gzをhtmlにすればOKです。dat.gzが見つからない場合は、拡張子をdatにして探してみてください。過去ログが存在するなら、dat.gzかdatのどちらかがあるはずです。過去ログ倉庫にもsubject.txtが存在する場合があります。場所は/板キー/kako/スレキーの上位4桁/スレキーの上位5桁/subject.txtになります。存在しない場合がほとんどですが。基本は以上の通りですが、まだ他にもパターンがあるようです。過去ログ倉庫を覗いてみると、次のような仕様の過去ログもあります。mentai(mukashi)DATファイルの場所は/takoまたはkitanetまたはlogまたはlog2またはmukashi/板キー/kako/スレキーの上位3桁/スレキー.datDAT書式は区切り文字がコンマの古いタイプで無圧縮。1999、pyon、kitanet、jbbs、2002a筆者はIDを持ってないので(以下略)。ログイン仕様サーバにはsubject.txtが存在するようで、場所は/板キー/subject.txtになります。当然ですが、DATはブラウザから見れません。ほかにも仕様があるみたいだけど、全てを把握するのは難しい。見つけた仕様を列挙しときます。closebbs=newsplus&key=1000000000&time=1&submit=書き込む&FROM=名前&mail=メール&MESSAGE=本文ポストするデータの内容bbs板キーkeyスレキーtime2ch側の書き込みフォームが生成された時刻。time関数の戻り値である。たいがいの2chブラウザはローカルで時刻を生成していたが、規制によって未来からの書き込みが禁止になった。ローカルの時計が狂っていると永久に書き込めないのである。そこで現在は、datを取得した時の応答ヘッダにあるDateヘッダの値から逆算するなどの工夫が取られている。2ch側では有効期限をチェックしていない、ちょっとアレな仕様のため、適当に大昔の時刻を入れても大丈夫なのである。submit書き込みボタンのキャプション。文字列はURLエスケープしておきましょう。これがないと「SJISで書いてね」とか怒られる。2chとお話しすると、まずこの罠に嵌ります。URLエスケープしておく必要があります。「エスケープ」→「%a5%a8%a5%b9%a5%b1%a1%bc%a5%d7」mailメール。URLエスケープしておく必要があります。URLエスケープしておく必要があります。MESSAGEは大文字です。sidセッションID。ログインすると発行されるあれです。ログインしていないなら不要。付与するなら、これもURLエスケープしておきます。クッキーについてNAME名前。URLエスケープしておく必要があります。URLエスケープしておく必要があります。SPIDまたはPON書き込み時に発行される、クッキーのSPID値またはPON値。値と名前を知るには、POSTすると返ってくる応答ヘッダのSet-Cookieヘッダの中身を調べてください。ホスト毎に発行され、IPアドレスや日付が変わると値が変わります。これがないと、クッキー確認画面より先へ進めません。これもURLエスケープしておきます。SPID(PON)はローカルに保存して再利用するようにします。値が不正でも、また発行されますから。expires(有効期限)有効期限はチェックしていないようです。応答ヘッダのクッキーを見て、一応付けておいた方がいいでしょう。書き込み確認いくつかの例を挙げてみます。パターンがあって難しいのが少々ネックになっています。<title>タグの中身</title>を調べる書き込みが成功すると、書きこみましたという文字列が入る書き込みが失敗すると、ERRORという文字列が入るサーバの負荷が高く、書き込めない場合は、お茶でもという文字列が入るクッキー確認の場合は、書き込み確認という文字列が入る書き込み失敗エラーの内容を知るには、最初にくる<b>タグの中身を調べます。お茶飲みエラーの場合は次のようなHTMLが表示されます。charset=x-sjis"><TITLE>お茶でも飲みましょう。</TITLE></HEAD>サーバの負荷が高いので書きこめません。以下)<hr>もちろん、このページをリロードするのも負荷かかります。</BODY></HTML>2chタグを調べる<html>タグの次にコメントタグ(以下、2chタグ)が入っていることがあります。-->タイトルタグと2chタグの両者を調べて、どちらかがtrueならば〜するという処理にするのが、現時点ではベストな方法かと思われます。管理側の通達により、確認画面を自動処理してスルーすることは緩やかに禁止されています。使ってるとクッキー確認のダイアログがしょっちゅうでるんですよね。スレッドを立てるスレッドを立てる動作は、レスを書き込む動作とほとんど共通であり、テストするのも困難なので、適当に説明します。POSTする場所/test/bbs.cgi/test/subbbs.cgiポストするデータの内容(レス書き込みと違う点)subjectにスレタイトルkeyは不要bbs.cgiに投げる場合、submitは「新規スレッド作成」subbbs.cgiに投げる場合、submitは「全責任を負うことを承諾して書き込む」クッキーレス書き込みの場合と同じですさてスレッドを立てる方法ですが、まずbbs.cgiに投げてみます。これだけでスレが立っちゃう板もあります。この場合のスレ立て成否確認方法は、レス書き込み確認と同じになります。中には、スレ立てにワンクッション置く板もあり、この場合は次のように表示されます。color=#FF0000>書き込み確認。</font><br><br>書き込みに関して様々なログ情報が記録されています。action="../test/subbbs.cgi">(以下略)この場合、subbbs.cgiにもう1回投げる必要があります。subbbs.cgiに投げた時のスレ立て成否確認方法は、失敗ならレス書き込み確認と同じになりますが、成功なら(以下作成中)面倒。板一覧2chの板一覧を調べるには、2chで使用しているbbsmenu.htmlから解析します。*.bbspink.comにマッチしたモノだけを抜き出せば、必要な板が揃うでしょう(www.2ch.netは除く)bbspinkは2chと同じ仕様なので含むことにしますが、まちBBSは2chと仕様が大きく異なるため除外することにします。bbsmenu.htmlは適当ぽい書式でちょっと怖いですが、実績があるのでまず大丈夫でしょう。板キー重複の問題です。将来に渡って重複しない保証はありません。現在では板キーの重複は皆無ですが、板キーで板を判断する場合は、常にこの問題があることを頭に入れておきましょう。ユーザエージェントDATを取得する際は、User-AgentがMonazillaでなければ基本的に取得できません。2chブラウザを作った場合には、Monazillaを名乗る必要があります。ブラウザ名/バージョン番号」となります。Monazillaを名乗るには、運営側の許可は必要なく、誰でも自由に行えるようです。ログインkage作者さんのサイトにログインについての詳細があります。そちらをお読みください。筆者はIDを持っていないので説明できません。板移転subject.txtが見つからない場合は、板が移転したと判断しても大丈夫でしょう。板が移転した場合、/板のキー/のHTMLに移転先が書いてあるので、それを調べるのがよいかと。100%確実ではないので、細心の注意が必要です。移転先のページがまた移転先のお知らせだったりすることもあるので。<title>タグの中身が2chbbs..だったら確実に移転です。移転先は最初にくる<a>タグの中に書いてあります。!</a>巡回HEADメソッドとIf-Modified-Sinceヘッダを利用して、DATが更新されているかどうかだけを調べるのがベストだと思いますが、どうなんでしょう。えいやーとGETメソッドを投げまくると、夜勤さんが卒倒しそうだし、ここは控えめに行きましょう。HTTP_NOT_MODIFIEDが返ってきます。これまでの経験によると、18時〜19時、20時〜22時は特に混雑する時間帯です。この負荷ピーク時の巡回を抑えれば、サーバに優しくなるでしょう。2chのURLオプション簡単に2chのURLとオプションを説明します。最新数字件のレスを表示する(1は表示される)&ls=数字n1を除外する&nofirst=truei携帯用(r.iができたから過去の遺物化に)&imode=true複数オプションにも対応してます。1を除外した最新10レスを携帯用に表示したい場合はl10niになります。昔はQUERY_STRING形式のURLが使われてましたが、現在ではPATH_INFO形式が主に使われています。QUERY_STRING形式でも動きますが、かっこわるいしレガシーなのでPATH_INFO形式を使いましょう。参考までに、携帯用のr.i(read.cgiの短縮形)というのもあります。http://ホスト名/test/r.i/板キー/スレキー/トリップとIDの算出方法サンプルプログラムをどうぞ。(Perl)トリップの算出トリップの算出(新鯖Ver)IDの算出IDの算出(昔Ver)トリップは書き込む前に知ることができる。IDは書き込むまで知ることができない。(IDからIPを割るのは不可能です)head.txt板のローカルルールが書かれたファイル。HTMLタグで書かれています。head.txtには<html>タグや<body>タグがないので、各ブラウザでhead.txtを表示するには適当にタグを付けてあげましょう。/板キー/head.txtにあります。UAにMonazillaを付けてgetしないと、取得できない板もあるようです。SETTING.TXT板の設定が書かれたファイル。/板キー/SETTING.TXTにあります。UAにMonazillaを付けてgetしないと、取得できない板もあるようです。設定の詳細は2ちゃんねる初心者のためのページで調べることができます。/_service/サーバの負荷率や、サーバに存在する板一覧ファイルなどが置いてあるディレクトリ。/_service/にあります。サーバ負荷監視所さんはこれを利用しているようですね。monazilla.orgmonazilla.orgは2ちゃんねるブラウザを開発するプログラマの集まりです。2chブラウザを作ろうとしているならば、monazillaに参加するといいかもしれません。monazillaには資料類も豊富にあるので、ブラウザ開発の参考になるでしょう。rawモードread.cgiにはrawモードというオプションがあります。rawモードを使用すると、目的のレスだけをDAT仕様で取得することができます。便利といえば便利ですが、通常の2chブラウザでrawモードを使用する必要性はほとんどないでしょう。read.cgiを呼び出すため、dat取得よりもサーバに対し負荷がかかりますし。rawモードの使用例subject.txtを全て取得するhttp://ホスト名/test/read.cgi/板キー/?raw=0.0subject.txtの最新50件を取得するhttp://ホスト名/test/read.cgi/板キー/?raw=0.0&ls=50subject.txtの30〜60件を取得するhttp://ホスト名/test/read.cgi/板キー/?raw=0.0&st=30&to=60datを全て取得するhttp://ホスト名/test/read.cgi/板キー/スレキー/?raw=0.0datの10〜20件までを取得するhttp://ホスト名/test/read.cgi/板キー/スレキー/?raw=0.0&st=10&to=20datの1を取得するhttp://ホスト名/test/read.cgi/板キー/スレキー/?raw=0.0&st=1&to=1datの30件目以降を取得するhttp://ホスト名/test/read.cgi/板キー/スレキー/?raw=0.0&st=30rawモードのオプションはQUERY_STRING形式のオプションとほとんど同じですが、目的のレスだけが出力される点で少々異なります。rawモードのオプションには標準でnオプション(1を除外する)が付いていると考えれば、QUERY_STRING形式のオプションと同じになります。gzipが必要であり、出力はgzip圧縮されて返ってきます。それと、User-Agentがモナジラだと弾かれたような気が。最近は、Accept-Encodingがなくても大丈夫なようです。転送量よりCPU、I/O負荷の方が問題になっているからだと思われますが。rawモードの出力は、1行目にステータス、2行目以降から要求されたデータになります。ステータス行の例を以下に示します。そんな板orスレッドないです。範囲指定を例に書式を説明します。