C#で2chのスレッドdat取得(差分も)すた2010年03月29日

このエントリーをはてなブックマークに追加
はてなブックマーク - C#で2chのスレッドdat取得(差分も)

C#で2chのSubject.txt取得に続いて、今回は個々のスレッドのdat取得。

前回とほとんど変わらないが差分の取得やらdat落ち判定やらで僅かに長くなった。

datファイルはhttp://サーバ/板名/dat/スレッド番号.datにある。

(例)http://yutori7.2ch.net/news4vip/dat/1269850034.dat

初回dat取得時に応答ヘッダのLast-Modified(更新時刻)とRange(ファイルサイズ)を取得、次回それを付加して差分のみ取得。


※わざわざ差分取得せず毎回全部取得も出来る。





private string LastModified;
private long Range;

public string GetDat(string URL)
{
    string board;
    string server;
    string no;

    Match m = Regex.Match(URL, @"http://(.*\.2ch\.net)/test/read\.cgi/(.*?)/([0-9]{10})/");
    server = m.Groups[1].Value;
    board = m.Groups[2].Value;
    no = m.Groups[3].Value;

    Encoding enc = Encoding.GetEncoding(932);
    HttpWebRequest req = null;
    try
    {
        req = (HttpWebRequest)WebRequest.Create(string.Format("http://{0}/{1}/dat/{2}.dat", server, board,no));
    }
    catch
    {
        return null;
    }

    // ポスト・データの作成
    req.Method = "GET";
    req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 GTB6 (.NET CLR 3.5.30729)";
    req.Referer = string.Format("http://{0}/{1}/", server, board);
    req.Accept = "gzip";
    req.Timeout = 20000;

    //差分だけ取得するかどうか
    if(LastModified!=null&&Range!=0)
    {
        req.IfModifiedSince = DateTime.Parse(LastModified);
        req.AddRange((Int32)Range);
    }

    //レスポンスの取得と読み込み
    string dat = null;
    try
    {
        WebResponse res = req.GetResponse();
        Stream resStream = res.GetResponseStream();
        StreamReader sr = new StreamReader(resStream, enc);
               
        dat = sr.ReadToEnd();

        //datの更新時間とサイズを取得、次回の差分取得に用いる
        LastModified = res.Headers["Last-Modified"];
        Range = long.Parse(res.Headers["Content-Length"]);
               
        if (((HttpWebResponse)res).StatusCode== HttpStatusCode.NonAuthoritativeInformation)
        {
            /*203 Non-Authoritative Information
            * Dat落ちして過去ログ倉庫から不完全に取得*/

        }

        sr.Close();
        resStream.Close();
    }
    catch (WebException ex)
    {
        if (ex.Status == WebExceptionStatus.ProtocolError)
        {
            if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotModified)
            {
                /*304 Not Modified
                 *前回からの差分(書き込み)なし*/

                return "";
            }
            else if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound || ((HttpWebResponse)ex.Response).StatusCode== HttpStatusCode.Found)
            {
                /*302 Foundまたは404 Not Found
                *指定したスレッドが見つからない*/

                return "";
            }
        }
    }
    catch
    {
        return null;
    }

    //受信したdat本文を返す
    return dat;
}

dat落ちしていてもステータスコードが203 Non-Authoritative Informationになるだけで、不完全なdatが取得できてしまう。
(このスレッドは過去ログ倉庫に格納されています云々)


GetDat("http://yutori7.2ch.net/test/read.cgi/news4vip/1269850034/");

とすればこんな感じで取得できる。

以下、名無しにかわりましてVIPがお送りします<><>2010/03/29(月) 17:07:14.44 ID:h1Hei7dW0<> 携帯持ってない俺はどうすりゃいいんだよ糞グーグルさん <>Googleアカウントの登録に携帯が必要になった件\n
以下、名無しにかわりましてVIPがお送りします<><>2010/03/29(月) 17:08:37.11 ID:6yWZS0KAP<> Google「Android携帯買えよ貧民」 <>\n



名前<>メール<>[日付] [ID] [BE-ID]<>本文<>(スレッドタイトル)\n

スレタイは1行目のみ。

参考:と~く2ちゃんねる

このエントリーをはてなブックマークに追加
はてなブックマーク - C#で2chのスレッドdat取得(差分も)

関連する記事

One Response to “C#で2chのスレッドdat取得(差分も)”

  1. nonoriri2012 より:

    ここのコードを使用させて頂いて、『JSON PARSE PROXY SERVER for 2ちゃんねる』なるものを作成しました。
    有難うございます。

Leave a Reply

Dansette