개요
프로젝트를 진행하다 보면 html 파일의 내용 일부를 가져와야 하는 경우가 있습니다. html 파일의 형식이 항상 동일하고 가져와야 하는 값이 고정되어 있다면 큰 문제가 되지 않습니다. 태그를 모두 제거한 후 처리하거나 파일 전체를 문자열로 취급하여 원하는 부분을 가져옵니다. 문제는 파일의 내용이 일정하지 않고 많은 값을 가져올 때 입니다. 태그를 제거하거나 문자열로 취급해서 찾기에는 너무 복잡하고 어렵습니다. 내용에 조금의 변화면 있어도 오류가 발생할 소지가 매우 높습니다. 이런 경우 Html Agility Pack 을 사용하면 쉽게 원하는 요소의 값을 가져올 수 있습니다.
Html Agility Pack
Html Agility Pack (HAP) 은 html 파서(Parser)입니다. 파일, 문자열, URL 로 부터 html 형식을 읽어들여 요소에 대한 값을 취하거나 변경할 수 있습니다. 설치는 비주얼 스튜디오 패키지 관리자 콘솔에서 다음과 같이 입력하면 됩니다.
PM>Install-Package HtmlAgilityPack -Version 1.6.15
설치 후 다음과 같이 읽어 들인 후 파싱하여 원하는 요소의 값을 가져오면 됩니다.
파싱(Parsing)
대부분 SelectNodes(), SelectSingleNode(String) 메소드를 이용해서 값을 가져오게 됩니다.
다음은 파싱 대상 html 파일 입니다.
<body> <div> <div> <div> <strong><span id="HomeDeviceName">Laser Printer</span></strong> <strong>192.168.1.120<span id="deviceIp" /></strong> </div> </div> <div> <h1>페이지</h1> <div> <div class="consumable-block-header"> <h2 id="black">black</h2> <p class="percentage">0%*</p> <p class="data"><span>ABCDEFG</span></p> <div class="color" style="border: solid 1px black"> <strong class="2" id="level">2%</strong> </div> </div> <p><span>상태</span><strong id="status">알수없음</strong></p> <p><span>남은 페이지</span><strong id="remainPage">1000</strong></p> <p><span>일련 번호</span><strong id="serialNumber">123456789</strong></p> <p><span>인쇄한 페이지 수</span><strong id="printCount">1234</strong></p> </div> </div> </div> </body>
각 요소를 가져오는 코드를 보겠습니다.
var suppliesPage = new HtmlAgilityPack.HtmlDocument(); suppliesPage.Load(suppliesPageFilePath, Encoding.UTF8); var data = suppliesPage.DocumentNode.SelectNodes("//div[@class='consumable-block-header']")[0].SelectNodes("p[@class='data']//span").First().InnerHtml.Trim(); //ABCDEFG var status = suppliesPage.DocumentNode.SelectNodes("//strong[@id='status']").First().InnerHtml.Trim(); //알수없음 var remainPage = suppliesPage.DocumentNode.SelectNodes("//strong[@id='remainPage']").First().InnerHtml.Trim(); //1000 var serialNumber = suppliesPage.DocumentNode.SelectNodes("//strong[@id='serialNumber']").First().InnerHtml.Trim(); //123456789 var printCount = suppliesPage.DocumentNode.SelectNodes("//strong[@id='printCount']").First().InnerHtml.Trim(); //1234
요소의 id 및 class로 값을 가져올 수 있습니다.
xpath 형식으로 기술하여 원하는 요소의 값을 가져올 수 있습니다
이상으로 Html Agility Pack 을 이용하여 html 파일을 파싱하는 방법을 알아봤습니다.