by WebSurfer
2012年8月10日 21:45
注意:
iframe に表示するページは親ページと同じドメインのものでないと、以下に紹介する方法では DOM は取得できないので注意してください(クロスサイトスクリプト対策だそうです)。
.NET Framework の WebBrowser に表示したページに iframe が含まれる場合、iframe の中の 要素 (HtmlElement) を取得するにはどうしたらいいかという話です。
ページが単一のドキュメントで構成されている場合は、WebBrowser.Document プロパティ で取得できる HtmlDocument オブジェクト から、HtmlDocument.GetElementById メソッドなどを使って、ドキュメントを構成する要素 (HtmlElement) を取得できます。
しかしながら、ページに iframe が含まれている場合、HtmlDocument オブジェクトや、その All プロパティで取得できる HtmlElementCollection オブジェクトから iframe の中の要素を直接取得することはできません。(iframe は取得できますが、その子要素は取得できません)
iframe の中の子要素 (HtmlElement) を取得するには一工夫必要です。では、どうしたらいいでしょう?
例として、以下のように iframe を持ち、iframe の src 属性にテキストボックス 2 つとボタン 1 つを持つログインページページを指定してあるページで、iframe の中の要素 (HtmlElement) を取得して操作することを考えます。
親ページ(iframe を持つ)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<h1>iframe 中の Login ページ</h1>
<iframe id="iframe1" src="168-Login.aspx" />
</body>
</html>
ログインページ(iframe に表示)
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
ID:<input id="Text1"
name="Text1"
type="text" />
<br />
PW:<input id="Text2"
name="Text2"
type="text" />
<br />
<input id="Submit1"
name="Submit1"
type="submit"
value="Login" />
</div>
</form>
</body>
</html>
上の「親ページ」を WebBrowser に表示したとします。
このとき、以下のコードでコメントアウトしたコードのように webBrowser1.Document.All で取得できる HtmlElementCollection には iframe の子要素は含まれないので id や pw は null になってしまいます。
iframe は WebBrowser コントロール内の別のウィンドウです。HtmlDocument.Window プロパティでドキュメントに関連付けられている HtmlWindow オブジェクトを取得し、HtmlWindow.Frames プロパティで Web ページ内で定義されている各 iframe 要素への参照を取得できます。(frame 要素の場合も同様です)
以下のようにして、iframe 内の要素 (HtmlElement) を取得して、操作することができます。
// これでは取得できない
//HtmlElement id =
// webBrowser1.Document.All.GetElementsByName("Text1")[0];
//HtmlElement pw =
// webBrowser1.Document.All.GetElementsByName("Text2")[0];
//id.InnerText = "loginName";
//pw.InnerText = "password";
//HtmlElement login =
// webBrowser1.Document.All.GetElementsByName("Submit1")[0];
//login.InvokeMember("click");
HtmlWindow iframe = webBrowser1.Document.Window.Frames[0];
HtmlElementCollection elements = iframe.Document.All;
HtmlElement id = elements.GetElementsByName("Text1")[0];
HtmlElement pw = elements.GetElementsByName("Text2")[0];
id.InnerText = "loginName";
pw.InnerText = "password";
HtmlElement login = elements.GetElementsByName("Submit1")[0];
login.InvokeMember("click");