|   | 
          
 
            
|  
              
 .NET TIPS 
クッキーを使ってWebページを取得するには?
デジタルアドバンテージ 遠藤 孝信 
              2005/07/15 | 
  | 
          
 
            
 
              
 
             | 
        
  最近ではユーザーの認証にクッキーを用いているWebサイトは多い(ASP.NETの「フォーム認証」もクッキーを利用している)。本稿では、このようなクッキー認証を行っているWebページにプログラムからアクセスする方法について解説する。
クッキー認証を行うWebサイトの仕組み
 最初にクッキー認証の仕組みについて簡単にまとめておこう。
 たいていの場合、クッキー認証を行っているWebサイトでは、ユーザーは最初にログイン・ページにアクセスし、ユーザーIDやパスワードを入力する。ログインが成功すれば、ブラウザはWebサイトからクッキーを受け取る(クッキーはファイルあるいはメモリ上に保存される)。
 
  | 
 
| クッキー認証の基本的な仕組み | 
 
 
 
|    | 
  | 
ログイン・ページで認証が成功すればクッキーがもらえる。 | 
 
 
|    | 
  | 
そのクッキーを持っていれば、認証が必要なページにアクセスできる。 | 
 
 
 | 
 以降のページ(認証が必要なページ)へのアクセスには、このクッキーが必要となる。クッキーを持っているユーザーがそれらのページにアクセスすると、ページ取得のリクエストとともにクッキーがWebサイトに送信される。これによりページの閲覧が許可されるため、ユーザーはそれらのページを見ることができる。
HttpWebRequestクラスのCookieContainerプロパティ
 クッキー認証を行っているWebサイトにプログラムからアクセスする場合にも、上記と同じような手順を行うことになる。
 以下では、WebRequestクラス/WebResponseクラス(ともにSystem.Net名前空間)のペアを利用してWebページにアクセスする場合のクッキーの利用について述べる。なおこれらのクラスを利用して、HTTPプロトコルのGETあるいはPOSTメソッドによりWebページにアクセスする基本的な方法については以下のTIPSでまとめているので、ご存じない方はまずそちらを参考にしていただきたい。
 プログラムでは、受け取ったクッキーを格納するためのCookieContainerクラス(System.Net名前空間)のオブジェクトをまず用意する。このオブジェクトは複数サイトの複数クッキーを格納できるストレージである(以降のコード例はC#の場合。VB.NETの場合はページ末尾のサンプル・プログラムを参照)。
CookieContainer cc = new CookieContainer();
 そして、ログイン・ページに対してIDやパスワードをPOSTする際のリクエスト(HttpWebRequestオブジェクト)を作成するときに、いま作成したCookieContainerオブジェクトをCookieContainerプロパティにセットしておく。
string url1 = "http://ログイン・ページのURL";
HttpWebRequest req1 = (HttpWebRequest)WebRequest.Create(url1);
req1.Method = "POST";
req1.CookieContainer = cc;
……
 このようにしてWebページにアクセスすれば(HttpWebRequestオブジェクトのGetRequestStreamメソッドを呼び出せば)、Webサイトから受け取ったクッキーがすべてCookieContainerオブジェクト(上記のコードでは変数cc)に格納される。
 以降、クッキー認証が必要なページにアクセスする場合には、クッキーが格納されているCookieContainerオブジェクトをリクエストのCookieContainerプロパティにセットしておくだけでよい。
string url2 = "http://認証が必要なページのURL";
HttpWebRequest req2 = (HttpWebRequest)WebRequest.Create(url2);
req2.Method = "GET"; // GETは既定値なのでこの行は省略可
req2.CookieContainer = cc;
……
 これにより、リクエストを発行する際にクッキーが送信されることになる。
クッキー認証を行うWebサイトにアクセスするサンプル・プログラム
 以下に、クッキー認証を行っているWebサイトのページにアクセスするサンプル・プログラムを示す。ここではアクセスするWebサイトとしてmixi(ミクシィ)を利用する。
 このプログラムでは、まずIDやパスワードをログイン・ページにPOSTし、クッキーを受け取る。そして受け取ったクッキーを用いて「足あと」ページ(アクセス・ログを閲覧できるページ)の内容を取得し、ログ部分を切り出して表示する。
 
// mixilog.cs 
 
using System; 
using System.IO; 
using System.Net; 
using System.Text; 
using System.Collections; 
 
public class MixiTool { 
  static Encoding encoder = Encoding.GetEncoding("EUC-JP"); 
 
  static string HttpGet(string url, CookieContainer cc) { 
 
    // リクエストの作成 
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); 
    req.CookieContainer = cc; 
 
    WebResponse res = req.GetResponse(); 
 
    // レスポンスの読み取り 
    Stream resStream = res.GetResponseStream(); 
    StreamReader sr = new StreamReader(resStream, encoder); 
    string result = sr.ReadToEnd(); 
    sr.Close(); 
    resStream.Close(); 
 
    return result; 
  } 
 
  static string HttpPost(string url, Hashtable vals, CookieContainer cc) { 
    string param = ""; 
    foreach (string k in vals.Keys) { 
      param += String.Format("{0}={1}&", k, vals[k]); 
    } 
    byte[] data = Encoding.ASCII.GetBytes(param); 
 
    // リクエストの作成 
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); 
    req.Method = "POST"; 
    req.ContentType = "application/x-www-form-urlencoded"; 
    req.ContentLength = data.Length; 
    req.CookieContainer = cc; 
 
    // ポスト・データの書き込み 
    Stream reqStream = req.GetRequestStream(); 
    reqStream.Write(data, 0, data.Length); 
    reqStream.Close(); 
 
    WebResponse res = req.GetResponse(); 
 
    // レスポンスの読み取り 
    Stream resStream = res.GetResponseStream(); 
    StreamReader sr = new StreamReader(resStream, encoder); 
    string result = sr.ReadToEnd(); 
    sr.Close(); 
    resStream.Close(); 
 
    return result; 
  } 
 
  static string Login(string id, string password, CookieContainer cc) { 
    // ログイン・ページへのアクセス 
    Hashtable vals = new Hashtable(); 
    vals["next_url"] = "/home.pl"; 
    vals["email"] = id; 
    vals["password"] = password; 
 
    string login = "http://mixi.jp/login.pl"; 
    return HttpPost(login, vals, cc); 
  } 
 
  static string ReadLog(CookieContainer cc) { 
    // 足あとページへのアクセス 
    string showlog = "http://mixi.jp/show_log.pl"; 
    return HttpGet(showlog, cc); 
  } 
 
  static void Main() { 
    string id = "あなたのメールアドレス"; 
    string password = "あなたのパスワード"; 
 
    CookieContainer cc = new CookieContainer(); 
 
    Login(id, password, cc); 
    string html = ReadLog(cc); 
 
    // ログ部分の切り出し(簡易版) 
    string[] lines = html.Split('\n'); 
    foreach (string line in lines) { 
      if (line.IndexOf("年") >= 0) { 
        string[] t = line.Split('<', '>'); 
        Console.WriteLine(t[0] + t[2]); 
      } 
    } 
    // 出力例: 
    // 2005年07月13日 16:54 XXXX 
    // 2005年07月12日 05:43 YY 
    // 2005年07月11日 22:50 ZZZ 
    // …… 
  } 
 
} 
 
// コンパイル方法:csc mixilog.cs
 | 
 
 
 | 
 
| mixi.jpにアクセスしログ・ページを取得するC#のサンプル・プログラム(mixilog.cs) | 
| 
 | 
 
 
 
' mixilog.vb 
 
Imports System 
Imports System.IO 
Imports System.Net 
Imports System.Text 
Imports System.Collections 
Imports Microsoft.VisualBasic 
 
Public Class MixiTool 
  Dim Shared encoder As Encoding = Encoding.GetEncoding("EUC-JP") 
 
  Shared Function HttpGet(url As String, cc As CookieContainer) As String 
 
    ' リクエストの作成 
    Dim req As HttpWebRequest _ 
      = CType(WebRequest.Create(url), HttpWebRequest) 
    req.CookieContainer = cc 
 
    Dim res As WebResponse = req.GetResponse() 
 
    ' レスポンスの読み取り 
    Dim resStream As Stream = res.GetResponseStream() 
    Dim sr As StreamReader = new StreamReader(resStream, encoder) 
    Dim result As String = sr.ReadToEnd() 
    sr.Close() 
    resStream.Close() 
 
    Return result 
  End Function 
 
  Shared Function HttpPost(url As String, vals As Hashtable, cc As CookieContainer) As String 
    Dim param As String = "" 
    For Each k As String In vals.Keys 
      param += String.Format("{0}={1}&", k, vals(k)) 
    Next 
    Dim data As byte() = Encoding.ASCII.GetBytes(param) 
 
    ' リクエストの作成 
    Dim req As HttpWebRequest _ 
      = CType(WebRequest.Create(url), HttpWebRequest) 
    req.Method = "POST" 
    req.ContentType = "application/x-www-form-urlencoded" 
    req.ContentLength = data.Length 
    req.CookieContainer = cc 
 
    ' ポスト・データの書き込み 
    Dim reqStream As Stream = req.GetRequestStream() 
    reqStream.Write(data, 0, data.Length) 
    reqStream.Close() 
 
    Dim res As WebResponse = req.GetResponse() 
 
    ' レスポンスの読み取り 
    Dim resStream As Stream = res.GetResponseStream() 
    Dim sr As StreamReader = new StreamReader(resStream, encoder) 
    Dim result As String = sr.ReadToEnd() 
    sr.Close() 
    resStream.Close() 
 
    Return result 
  End Function 
 
  Shared Function Login(id As String, password As String, cc As CookieContainer) As String 
    ' ログイン・ページへのアクセス 
    Dim vals As Hashtable = new Hashtable() 
    vals("next_url") = "/home.pl" 
    vals("email") = id 
    vals("password") = password 
 
    Dim loginUrl As String = "http://mixi.jp/login.pl" 
    Return HttpPost(loginUrl, vals, cc) 
  End Function 
 
  Shared Function ReadLog(cc As CookieContainer) As String 
    ' 足あとページへのアクセス 
    Dim showlog As String = "http://mixi.jp/show_log.pl" 
    Return HttpGet(showlog, cc) 
  End Function 
 
  Shared Sub Main() 
    Dim id As String = "あなたのメールアドレス" 
    Dim password As String = "あなたのパスワード" 
 
    Dim cc As CookieContainer = new CookieContainer() 
 
    Login(id, password, cc) 
    Dim html As String = ReadLog(cc) 
 
    ' ログ部分の切り出し(簡易版) 
    Dim lines As String() = html.Split(vbLf) 
    For Each line As String In lines 
      If line.IndexOf("年") >= 0 
        Dim t As String() = line.Split(New Char() {"<", ">"}) 
        Console.WriteLine(t(0) + t(2)) 
      End If 
    Next 
    ' 出力例: 
    ' 2005年07月13日 16:54 XXXX 
    ' 2005年07月12日 05:43 YY 
    ' 2005年07月11日 22:50 ZZZ 
    ' …… 
  End Sub 
End Class 
 
' コンパイル方法:vbc /r:System.dll mixilog.vb
 | 
 
 
 | 
 
| mixi.jpにアクセスしログ・ページを取得するVB.NETのサンプル・プログラム(mixilog.vb) | 
| 
 | 
 実際にこのプログラムを利用する場合には、Mainメソッド内で定義している文字列変数idおよびpasswordの内容を自分のアカウントのものに書き換える必要がある。
 
        
 
|  
 | 
 
generated by  
 | 
 
 
 |