|
.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
|
|