C# -- IE automation #4 -- html 구조 파헤치기
C# -- IE automation #4 -- html 구조 파헤치기
참고 : https://msdn.microsoft.com/ko-kr/library/system.windows.forms.htmldocument(v=vs.110).aspx
--> HtmlDocument 클래스 (mshtml 과는 약간 다르지만, 비슷한 사용법이다.)
https://msdn.microsoft.com/ko-kr/library/aa703928(v=vs.85).aspx -->IHTMLElementCollection interface
https://msdn.microsoft.com/ko-kr/library/aa752279(v=vs.85).aspx --> IHTMLElement interface
https://msdn.microsoft.com/ko-kr/library/aa704078(v=vs.85).aspx --> IHTMLDOMNode interface
https://msdn.microsoft.com/ko-kr/library/hh870185(v=vs.85).aspx --> nodeType
<< 미션 >>
mshtml.IHTMLElement 과 mshtml.IHTMLDOMNode 의 사용법을 알아보자.
** IE (internet explorer) 통하여 읽어들인 HTML 구성 요소들을 분석하기 위해서는 2가지 접근 방법을 고려하자.
1. mshtml.IHTMLElement 사용하여 각각의 요소를 접근 분석한다.
2. mshtml.IHTMLDOMNode 를 사용하여 각각의 node 에 접근 분석한다.
<< 1. mshtml.IHTMLElement 사용하기 >>
using System; | |
namespace IE_IHTMLElement | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
SHDocVw.InternetExplorer IE = new SHDocVw.InternetExplorer(); | |
// object url = "http://example.com/"; | |
dynamic url = "http://petpad.co.kr/"; | |
IE.Visible = true; | |
IE.Navigate2(ref url); | |
// 페이지 로딩이 완료될때까지 기다림.... | |
while (IE.Busy == true || IE.ReadyState != SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE) | |
{ | |
System.Threading.Thread.Sleep(100); | |
} | |
mshtml.HTMLDocument doc = IE.Document; | |
mshtml.IHTMLElementCollection elemColl = null; | |
elemColl = doc.getElementsByTagName("div") as mshtml.IHTMLElementCollection; | |
Console.WriteLine("div 태그 갯수 == " + elemColl.length); | |
// mshtml.IHTMLElement 로 각각의 element 꺼내어 검사함. | |
foreach (mshtml.IHTMLElement elem in elemColl) | |
{ | |
Console.WriteLine("\n"); | |
Console.WriteLine(" elem.GetType() ===> " + elem.GetType().ToString()); | |
Console.WriteLine(" tagName == " + elem.tagName); | |
Console.WriteLine("\n"); | |
Console.WriteLine(" innerText == " + elem.innerText); | |
Console.WriteLine("\n"); | |
Console.WriteLine(" outerHTML == " + elem.outerHTML); | |
Console.WriteLine("\n"); | |
Console.WriteLine(" children element 갯수 == " + elem.children.length); // text 제외한, tag 갯수만 포함. | |
if (elem.getAttribute("id") != null) | |
{ | |
Console.WriteLine(" id == " + elem.getAttribute("id")); | |
} | |
Console.WriteLine(" =================================================="); | |
} | |
Console.ReadLine(); // Enter 치면 터미널 종료! | |
} | |
} | |
} |
mshtml.HTMLDocument doc = IE.Document;
doc.getElementById --> mshtml.IHTMLElement 반환 ==> 바로 사용가능
doc.getElementsByTagName --> mshtml.IHTMLElementCollection 반환 ==> for loop 사용
doc.getElementsByName --> mshtml.IHTMLElementCollection 반환 ==> for loop 사용
<< 2. mshtml.IHTMLDOMNode 사용하기 >>
using System; | |
namespace IE_IHTMLDOMNode | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
SHDocVw.InternetExplorer IE = new SHDocVw.InternetExplorer(); | |
// object url = "http://example.com/"; | |
dynamic url = "http://petpad.co.kr/"; | |
IE.Visible = true; | |
// IE.Navigate2(ref url, ref Empty, ref Empty, ref Empty, ref Empty); | |
IE.Navigate2(ref url); | |
// 페이지 로딩이 완료될때까지 기다림.... | |
while (IE.Busy == true || IE.ReadyState != SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE) | |
{ | |
System.Threading.Thread.Sleep(100); | |
} | |
mshtml.HTMLDocument doc = IE.Document; | |
mshtml.IHTMLElementCollection elemColl = doc.getElementsByTagName("div") as mshtml.IHTMLElementCollection; | |
Console.WriteLine("div 태그 갯수 == " + elemColl.length); | |
// mshtml.IHTMLElement 대신에 mshtml.IHTMLDOMNode 로 각각의 element 꺼내어 검사함. | |
foreach (mshtml.IHTMLDOMNode node in elemColl) | |
{ | |
Console.WriteLine(node.ToString()); | |
// elem.hasChildNodes() ==> 자식 노드 있으면 True 반환, 없으면 False 반환 | |
if (node.hasChildNodes()) | |
{ | |
Console.WriteLine("\n\n >>>>> 자식노드 크기 === " + node.childNodes.length); // text 갯수 + tag 갯수 | |
foreach (mshtml.IHTMLDOMNode child in node.childNodes) | |
{ | |
// IHTMLDOMNode.nodeType | |
// ---> int 형 (1 or 3) 반환 (1: element node, 3: text nodes) | |
Console.WriteLine("nodeType == " + child.nodeType); | |
// IHTMLDOMNode.nodeName | |
// ---> 태그이름 출력 (텍스트면 #text 출력함) | |
Console.WriteLine("nodeName (태그 이름) == " + child.nodeName); | |
if (child.nodeType == 1) // element node | |
{ | |
Console.WriteLine("-----element node ------------"); | |
Console.WriteLine(" +++ hasChildNodes ==> " + child.hasChildNodes()); | |
} else if (child.nodeType == 3) // text node 인 경우에만 nodeValue 출력. | |
{ | |
Console.WriteLine("-----text node ------------"); | |
Console.WriteLine("nodeValue == |{0}|", child.nodeValue); // 공백도 인식함. IHTMLElement 와 차이점 | |
} | |
Console.WriteLine("child.attributes ===> ", child.attributes); | |
} | |
Console.WriteLine("++++++++++++++++++++++++++++++++++++++++++++++++\n\n"); | |
} | |
} | |
Console.ReadLine(); // Enter 치면 터미널 종료... | |
} | |
} | |
} |
-- 33번째 줄의 출력 결과 해석
; Console.WriteLine(node.ToString());
; mshtml.IHTMLDOMNode node.ToString() 을 의미함.
mshtml.HTMLHtmlElementClass <html>
mshtml.HTMLHeadElementClass <head>
mshtml.HTMLBodyClass <body>
mshtml.HTMLDivElementClass <div>
mshtml.HTMLHeaderElementClass <h1>, <h2>, ...
mshtml.HTMLBRElementClass <br>
mshtml.HTMLParaElementClass <p>
*** mshtml.IHTMLDOMNode 에서는 nodeType 이 text node 인 경우,
mshtml.IHTMLElement 인 경우에는 인식못하는 공백도 인식한다.