본문
HtmlAgilityPack으로 html문서 파싱하기 + Preference사용하기
안드로이드에 SharedPreferences가 있다면, .net에는 Preference가 있다. 이 둘은 프로젝트 내에 파일로서 존재하여, 사용자가 원하는 변수를 다른 파일 처리 없이 언제든 손쉽게 불러오고 저장할 수 있는 기능을 제공한다. 이번에 HtmlAgilityPack을 사용해보다가 생각나서 Preference를 사용하기로 하였다. 사실 IEEE Xplorer 웹페이지 파서를 만들려고 했는데 한번 로딩하는것이 너무 오래걸려서 캐시 파일을 만들어서 처리를 할까 하다가 Preference를 사용하였다.
Preference의 값은 프로젝트 속성->설정 페이지에서 사용하고자 하는 변수를 등록하여 사용할 수 있으며, 특정 폴더내의 user.config(범위가 사용자로 지정된 경우) 에 저장된다. 위 프로그램에서의 경로는 아래와 같았으며, 즉 사용자 폴더의 AppData\Local\ 아래에서 프로젝트 명과 버전으로 이루어진 폴더 아래의 user.config에 위치한다.
"C:\Users\na\AppData\Local\WindowsFormsApplication3\WindowsFormsApplication3._Url_3jvpioyk0f5gnsilizyescvvfuy5ji5n\1.0.0.0"
HtmlAgilityPack은 XPath 와 Linq to Objects 기법을 사용하여 문서의 element에 접근할 수 있도록 해주는 라이브러리이다. 기존 .net framework에서의 라이브러리들과는 다르게 malformed된 문서도 (상대적으로) 잘 처리해준다. XPath의 간단한 설명과 예제는 다음 페이지에서 살펴볼 수 있다 (http://www.w3schools.com/xpath/xpath_syntax.asp) 구글 개발자 도구에서의 Copy XPath기능을 사용하면 파싱 작업을 편리하게 진행할 수 있다(라고 하지만 간혹 안되는 경우가 있긴 하다..)
하지만 아래의 프로그램을 만들다보니 문제가 발생했는데, 그것은 TextBox에서 문자열 길이의 한계가 있어서 전체 소스가 저장되지 않은 문제였고, MaxLength 속성을 0으로 설정해주면 이는 해결된다. 지난번 글에서는 ('C#에서 CsQuery 사용 + NuGet에서 CS0246 오류 해결하기') CsQuery를 다루었는데, 그때그때 상황에 맞게 사용하면 될 것 같다(참고로 CsQuery의 외부라이브러리 크기가 1mb가 넘었지만 HtmlAgilityPack은 500kb가 되지 않았다--.net framework 부분을 많이 사용해서 그런가)
public Form1() {
InitializeComponent();
textBox2.Text=Properties.Settings.Default.sourcecode;
}
private void button1_Click(object sender, EventArgs e) {
textBox3.Text = "";
Properties.Settings.Default.sourcecode = textBox2.Text;
Properties.Settings.Default.Save();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
try {
doc.LoadHtml(textBox2.Text);
foreach (HtmlNode link in doc.DocumentNode.SelectNodes(@textBox1.Text)) {
textBox3.Text += link.OuterHtml.Trim() + "\r\n=====================\r\n";
}
}
catch (Exception ee) {
textBox3.Text = ee.StackTrace;
}
}
댓글