본문 바로가기

Develop

[C#] HtmlAgilityPack 사용해서 HTML 파싱하기

HtmlAgilityPack

HtmlAgilityPack은 C#에서 HTML을 쉽게 파싱하기 위한 라이브러리로 NuGet에서 다운받을 수 있다.

WebBrowser 같은 기존의 번거로운 방법보다 훨씬 간편하게 이용할 수 있다.

웹페이지에 직접적으로 접근하여 Html을 받아오거나, 기존의 Html을 이용해서 파싱하는 방법 모두 사용할 수 있다.

 

Html 불러오기 (HtmlDocument)

웹페이지에서 불러오기

string url = "https://euliciel.tistory.com"

HtmlWeb web = new HtmlWeb();
HtmlDocument htmlDoc = web.Load(url);

Html String 에서 불러오기

string html = "<html>~</html>";

HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);

 

웹페이지 혹은 Html 데이터를 통해 파싱의 기본이 되는 파서인 HtmlDocument를 생성한다.

이 외에도 WebBrowser를 통해 받아오는 방식이나 파일을 통해 불러올 수도 있다.

 

노드 찾기 (Selectors)

HtmlAgilityPack은 단일 노드를 찾는 것과 여러 개의 노드를 찾는 두 가지 방법을 제공한다. 이 두 방법 모두 XPath 문법을 따르기 때문에 해당 문법을 알 필요가 있다.

단일 노드 검색

HtmlNode bodyNode = htmlDoc.DocumentNode.SelectSingleNode("body");

HtmlNode inputNode = bodyNode.SelectSingleNode("//div/input");
HtmlNode inputNode2 = bodyNode.SelectSigneNode("div/input");

HtmlNode divNode = bodyNode.SelectSingleNode("div[@id='divID']");
HtmlNode inputNode3 = divNode.SelectSigleNode("input[@class='inputClass']");

특정 노드로부터 SelectSingleNode 함수를 사용해서 자식 노드들을 검색한다. "div/input"과 같이 경로를 지정한 검색을 할 수도 있다. 이때 경로를 "//"로 시작한다면 자식 노드가 아닌 전체 노드 중에서 검색하게 된다.

또한 특정 아이디나 클래스 등의 어트리뷰트를 가진 노드도 검색할 수 있다. 이때는 [@attribute='value'] 형식으로 사용한다.

여러 노드 검색

HtmlNodeCollection nodes = bodyNode.SelectNodes("td");

HtmlNode firstNode = nodes.First();
for(int i=0; i<nodes.Count; i++) {
    string text = nodes[0].InnerText;
}

검색하는 방법은 단일 노드를 검색할 때와 동일하다. 원하는 노드들의 경로를 넣으면 이번에는 HtmlNodeCollection이라는 노드들의 리스트로 결과값을 받을 수 있다. 이 리스트는 우리가 자주 사용하는 일반적인 리스트와 똑같이 사용할 수 있다.

 

노드 살펴보기

원하는 HtmlNode를 찾았으면 이제는 데이터를 가져올 차례이다.

주로 해당 노드의 텍스트 데이터를 가져오는 InnerText와 해당 노드의 Html 데이터를 가져오는 HtmlText를 많이 사용하게 된다. 그 외에도 자식 노드들을 간편하게 수정하는 여러 함수들이 제공된다.

HtmlNodeCollection divNodes = htmlDoc.DocumentNode.SelectNodes("div");

foreach(HtmlNode node in divNodes) {
    HtmlNode span = node.SelectSingleNode("span[@class='name']");
    string data = span.InnerText;
    
    HtmlNode href = node.SelectSingleNode("a");
    string link = href.GetAttributeValue("href", "");
}

위 예제는 Html에서 div노드를 모두 찾아 해당 노드 아래의 span 노드와 a노드를 찾아 내부 텍스트와 이미지 링크를 추출하는 코드이다. 이 외에도 여러가지 간편한 사용법은 공식 홈페이지 문서에 잘 정리되어 있다.

 

Unity에서 사용하기

추가로 C#에서 동작하는 라이브러리이기 때문에 Unity 개발자들도 유용하게 사용할 수 있다.

해당 라이브러리를 Unity에서 사용하기 위해서는 라이브러리의 dll을 Assets 하단으로 복사해주어야 한다.

NuGet을 통해 다운로드 받았다면 Packages 폴더에서 해당 dll을 찾을 수 있다.