C# Web Scraping

C# -- IE automation #4 -- html 구조 파헤치기

자유프로그램 2016. 2. 9. 16:40
반응형

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 인 경우에는 인식못하는 공백도 인식한다.




반응형